Skip to content

Commit 6f245ea

Browse files
Karthikeyan PeriyasamyJeff Johnson
authored andcommitted
wifi: ath12k: introduce device group abstraction
Currently, single device is probed, and once firmware is ready, the device is registered to mac80211. For Multi-Link Operation, different bands of different devices or same device are part of a single wiphy and for this, hardware device group abstraction is needed. Hardware device group abstraction - when there are multiple devices (with single radio or dual radio) that are connected by any means of interface for communicating between them, then these devices can be combined together as a single group using a group id to form a group abstraction and register to mac80211. The grouping information of multiple devices would be based on device tree during device probe (will be implemented in future patches). If no such information is available, then a single device will be part of group abstraction and registered to mac80211, else multiple devices advertised in device tree are combined and then registered to mac80211. For device group abstraction, a base structure ath12k_hw_group (ag) and the helpers are implemented. These helpers are used during device probe and mapping the group to the devices involved. An illustration of how multiple devices might be combined together in future based on group id: +------------------------------------------------------------------------+ | +-------------------------------------+ +-------------------+ | | | +-----------+ | | +-----------+ | | +-----------+ | | | | | ar (2GHz) | | | | ar (5GHz) | | | | ar (6GHz) | | | | | +-----------+ | | +-----------+ | | +-----------+ | | | | ath12k_base (ab) | | ath12k_base (ab) | | | | (Dual band device) | | | | | +-------------------------------------+ +-------------------+ | | ath12k_hw_group (ag) based on group id | +------------------------------------------------------------------------+ In the above representation, two devices are combined into single group based on group id. Add base code changes where single device would be part of a group with an invalid group id forming an group abstraction. Multi device grouping will be introduced in future. 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 46d16f7 commit 6f245ea

File tree

3 files changed

+236
-13
lines changed

3 files changed

+236
-13
lines changed

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

Lines changed: 218 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ unsigned int ath12k_debug_mask;
2222
module_param_named(debug_mask, ath12k_debug_mask, uint, 0644);
2323
MODULE_PARM_DESC(debug_mask, "Debugging mask");
2424

25+
/* protected with ath12k_hw_group_mutex */
26+
static struct list_head ath12k_hw_group_list = LIST_HEAD_INIT(ath12k_hw_group_list);
27+
28+
static DEFINE_MUTEX(ath12k_hw_group_mutex);
29+
2530
static int ath12k_core_rfkill_config(struct ath12k_base *ab)
2631
{
2732
struct ath12k *ar;
@@ -1244,27 +1249,112 @@ static void ath12k_core_panic_notifier_unregister(struct ath12k_base *ab)
12441249
&ab->panic_nb);
12451250
}
12461251

1247-
int ath12k_core_init(struct ath12k_base *ab)
1252+
static inline
1253+
bool ath12k_core_hw_group_create_ready(struct ath12k_hw_group *ag)
12481254
{
1249-
int ret;
1255+
lockdep_assert_held(&ag->mutex);
12501256

1251-
ret = ath12k_core_soc_create(ab);
1252-
if (ret) {
1253-
ath12k_err(ab, "failed to create soc core: %d\n", ret);
1254-
return ret;
1257+
return (ag->num_probed == ag->num_devices);
1258+
}
1259+
1260+
static struct ath12k_hw_group *ath12k_core_hw_group_alloc(u8 id, u8 max_devices)
1261+
{
1262+
struct ath12k_hw_group *ag;
1263+
1264+
lockdep_assert_held(&ath12k_hw_group_mutex);
1265+
1266+
ag = kzalloc(sizeof(*ag), GFP_KERNEL);
1267+
if (!ag)
1268+
return NULL;
1269+
1270+
ag->id = id;
1271+
ag->num_devices = max_devices;
1272+
list_add(&ag->list, &ath12k_hw_group_list);
1273+
mutex_init(&ag->mutex);
1274+
1275+
return ag;
1276+
}
1277+
1278+
static void ath12k_core_hw_group_free(struct ath12k_hw_group *ag)
1279+
{
1280+
mutex_lock(&ath12k_hw_group_mutex);
1281+
1282+
list_del(&ag->list);
1283+
kfree(ag);
1284+
1285+
mutex_unlock(&ath12k_hw_group_mutex);
1286+
}
1287+
1288+
static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *ab)
1289+
{
1290+
u32 group_id = ATH12K_INVALID_GROUP_ID;
1291+
struct ath12k_hw_group *ag;
1292+
1293+
lockdep_assert_held(&ath12k_hw_group_mutex);
1294+
1295+
/* The grouping of multiple devices will be done based on device tree file.
1296+
* TODO: device tree file parsing to know about the devices involved in group.
1297+
*
1298+
* The platforms that do not have any valid group information would have each
1299+
* device to be part of its own invalid group.
1300+
*
1301+
* Currently, we are not parsing any device tree information and hence, grouping
1302+
* of multiple devices is not involved. Thus, single device is added to device
1303+
* group.
1304+
*/
1305+
ag = ath12k_core_hw_group_alloc(group_id, 1);
1306+
if (!ag) {
1307+
ath12k_warn(ab, "unable to create new hw group\n");
1308+
return NULL;
12551309
}
12561310

1257-
ret = ath12k_core_panic_notifier_register(ab);
1258-
if (ret)
1259-
ath12k_warn(ab, "failed to register panic handler: %d\n", ret);
1311+
ath12k_dbg(ab, ATH12K_DBG_BOOT, "single device added to hardware group\n");
12601312

1261-
return 0;
1313+
ab->device_id = ag->num_probed++;
1314+
ag->ab[ab->device_id] = ab;
1315+
ab->ag = ag;
1316+
1317+
return ag;
12621318
}
12631319

1264-
void ath12k_core_deinit(struct ath12k_base *ab)
1320+
void ath12k_core_hw_group_unassign(struct ath12k_base *ab)
12651321
{
1266-
ath12k_core_panic_notifier_unregister(ab);
1322+
struct ath12k_hw_group *ag = ab->ag;
1323+
u8 device_id = ab->device_id;
1324+
int num_probed;
1325+
1326+
if (!ag)
1327+
return;
1328+
1329+
mutex_lock(&ag->mutex);
1330+
1331+
if (WARN_ON(device_id >= ag->num_devices)) {
1332+
mutex_unlock(&ag->mutex);
1333+
return;
1334+
}
1335+
1336+
if (WARN_ON(ag->ab[device_id] != ab)) {
1337+
mutex_unlock(&ag->mutex);
1338+
return;
1339+
}
1340+
1341+
ag->ab[device_id] = NULL;
1342+
ab->ag = NULL;
1343+
ab->device_id = ATH12K_INVALID_DEVICE_ID;
1344+
1345+
if (ag->num_probed)
1346+
ag->num_probed--;
12671347

1348+
num_probed = ag->num_probed;
1349+
1350+
mutex_unlock(&ag->mutex);
1351+
1352+
if (!num_probed)
1353+
ath12k_core_hw_group_free(ag);
1354+
}
1355+
1356+
static void ath12k_core_device_cleanup(struct ath12k_base *ab)
1357+
{
12681358
mutex_lock(&ab->core_lock);
12691359

12701360
ath12k_hif_irq_disable(ab);
@@ -1274,8 +1364,123 @@ void ath12k_core_deinit(struct ath12k_base *ab)
12741364
ath12k_core_stop(ab);
12751365

12761366
mutex_unlock(&ab->core_lock);
1367+
}
12771368

1278-
ath12k_core_soc_destroy(ab);
1369+
static void ath12k_core_hw_group_destroy(struct ath12k_hw_group *ag)
1370+
{
1371+
struct ath12k_base *ab;
1372+
int i;
1373+
1374+
if (WARN_ON(!ag))
1375+
return;
1376+
1377+
for (i = 0; i < ag->num_devices; i++) {
1378+
ab = ag->ab[i];
1379+
if (!ab)
1380+
continue;
1381+
1382+
ath12k_core_soc_destroy(ab);
1383+
}
1384+
}
1385+
1386+
static void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
1387+
{
1388+
struct ath12k_base *ab;
1389+
int i;
1390+
1391+
if (!ag)
1392+
return;
1393+
1394+
mutex_lock(&ag->mutex);
1395+
1396+
for (i = 0; i < ag->num_devices; i++) {
1397+
ab = ag->ab[i];
1398+
if (!ab)
1399+
continue;
1400+
1401+
ath12k_core_device_cleanup(ab);
1402+
}
1403+
1404+
mutex_unlock(&ag->mutex);
1405+
}
1406+
1407+
static int ath12k_core_hw_group_create(struct ath12k_hw_group *ag)
1408+
{
1409+
struct ath12k_base *ab;
1410+
int i, ret;
1411+
1412+
lockdep_assert_held(&ag->mutex);
1413+
1414+
for (i = 0; i < ag->num_devices; i++) {
1415+
ab = ag->ab[i];
1416+
if (!ab)
1417+
continue;
1418+
1419+
mutex_lock(&ab->core_lock);
1420+
1421+
ret = ath12k_core_soc_create(ab);
1422+
if (ret) {
1423+
mutex_unlock(&ab->core_lock);
1424+
ath12k_err(ab, "failed to create soc core: %d\n", ret);
1425+
return ret;
1426+
}
1427+
1428+
mutex_unlock(&ab->core_lock);
1429+
}
1430+
1431+
return 0;
1432+
}
1433+
1434+
int ath12k_core_init(struct ath12k_base *ab)
1435+
{
1436+
struct ath12k_hw_group *ag;
1437+
int ret;
1438+
1439+
ret = ath12k_core_panic_notifier_register(ab);
1440+
if (ret)
1441+
ath12k_warn(ab, "failed to register panic handler: %d\n", ret);
1442+
1443+
mutex_lock(&ath12k_hw_group_mutex);
1444+
1445+
ag = ath12k_core_hw_group_assign(ab);
1446+
if (!ag) {
1447+
mutex_unlock(&ath12k_hw_group_mutex);
1448+
ath12k_warn(ab, "unable to get hw group\n");
1449+
return -ENODEV;
1450+
}
1451+
1452+
mutex_unlock(&ath12k_hw_group_mutex);
1453+
1454+
mutex_lock(&ag->mutex);
1455+
1456+
ath12k_dbg(ab, ATH12K_DBG_BOOT, "num devices %d num probed %d\n",
1457+
ag->num_devices, ag->num_probed);
1458+
1459+
if (ath12k_core_hw_group_create_ready(ag)) {
1460+
ret = ath12k_core_hw_group_create(ag);
1461+
if (ret) {
1462+
mutex_unlock(&ag->mutex);
1463+
ath12k_warn(ab, "unable to create hw group\n");
1464+
goto err;
1465+
}
1466+
}
1467+
1468+
mutex_unlock(&ag->mutex);
1469+
1470+
return 0;
1471+
1472+
err:
1473+
ath12k_core_hw_group_destroy(ab->ag);
1474+
ath12k_core_hw_group_unassign(ab);
1475+
return ret;
1476+
}
1477+
1478+
void ath12k_core_deinit(struct ath12k_base *ab)
1479+
{
1480+
ath12k_core_panic_notifier_unregister(ab);
1481+
ath12k_core_hw_group_cleanup(ab->ag);
1482+
ath12k_core_hw_group_destroy(ab->ag);
1483+
ath12k_core_hw_group_unassign(ab);
12791484
}
12801485

12811486
void ath12k_core_free(struct ath12k_base *ab)

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,20 @@ struct ath12k_soc_dp_stats {
816816
struct ath12k_soc_dp_tx_err_stats tx_err;
817817
};
818818

819+
/* Holds info on the group of devices that are registered as a single
820+
* wiphy, protected with struct ath12k_hw_group::mutex.
821+
*/
822+
struct ath12k_hw_group {
823+
struct list_head list;
824+
u8 id;
825+
u8 num_devices;
826+
u8 num_probed;
827+
struct ath12k_base *ab[ATH12K_MAX_SOCS];
828+
829+
/* protects access to this struct */
830+
struct mutex mutex;
831+
};
832+
819833
/* Master structure to hold the hw data which may be used in core module */
820834
struct ath12k_base {
821835
enum ath12k_hw_rev hw_rev;
@@ -1005,6 +1019,8 @@ struct ath12k_base {
10051019

10061020
struct notifier_block panic_nb;
10071021

1022+
struct ath12k_hw_group *ag;
1023+
10081024
/* must be last */
10091025
u8 drv_priv[] __aligned(sizeof(void *));
10101026
};
@@ -1035,6 +1051,7 @@ int ath12k_core_resume_early(struct ath12k_base *ab);
10351051
int ath12k_core_resume(struct ath12k_base *ab);
10361052
int ath12k_core_suspend(struct ath12k_base *ab);
10371053
int ath12k_core_suspend_late(struct ath12k_base *ab);
1054+
void ath12k_core_hw_group_unassign(struct ath12k_base *ab);
10381055

10391056
const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab,
10401057
const char *filename);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,7 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
17251725
if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
17261726
ath12k_pci_power_down(ab, false);
17271727
ath12k_qmi_deinit_service(ab);
1728+
ath12k_core_hw_group_unassign(ab);
17281729
goto qmi_fail;
17291730
}
17301731

0 commit comments

Comments
 (0)