From patchwork Mon May 6 17:39:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harshitha Prem X-Patchwork-Id: 13655854 X-Patchwork-Delegate: kvalo@adurom.com Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18C0E158201 for ; Mon, 6 May 2024 17:39:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715017201; cv=none; b=XcdYLI3t9E54o2WXzslh7MHb598Jb/iV7HaPrJPfE10Rm8Vi1+7lYV9h+uqRz2whcUZTXYQ4JkhvXHYTUQJs7bZPnc0f4wsX5VXWNTICiRJ7puVol66zojBVA1X93gqPHba+fxFmURfchuNReiD6vUskzjly9dy9S8v3O0LbKL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715017201; c=relaxed/simple; bh=lbqjwsi+ae0kGWZoGStCbY90TsEtlENLSfUF236hcyI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mpyeouSF6iFtC9sF5iEk9GuZt6DHJp9pkDpfkRH7ksGFhPB7fGzeAnothTmiabAup4JFViZWNMJ4sSeKSrF/AASp7iXPaXJ6SlyBle4c0T3OZPHxkWMS6oY1WgMOiJj608X/znDFODjQd3cxC0nzT/oAJe7QtcYvvUkbAsj6ilk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=qualcomm.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=kM5m7Xxj; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="kM5m7Xxj" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 446FLoUi005876; Mon, 6 May 2024 17:39:56 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=qcppdkim1; bh=U9SZGyB KQg4e+MC0p7yizc9nniKWjMgeEaeNGbpITUg=; b=kM5m7Xxj/PHtvg98QLPaRGq LFHk1Vw2BkZQLXZtpacgklVShJv0Fvy1M66Li5AqduoG6vAXfAyO6+3zp7bpGhtp Aq1tI+4V/Y4WWgXymL7MMc2YxasrApGLJoEdW4mu9spM010zgu+go/Brfsxt7Edp 0KFxvqYSnrhqAwMiWlgSdW91/+WnrsKB733QqyQONLqQSefO+Z0Naen3yrub2RNP Ynk14TDX4VS9uGQzZ7Q7bGxjFp2G6s/aFNPD7D6MQVmdKT9dTVs5RbN/xWYEW5lM 3QMMjYIl7AgIbu1bX/vW3fT8wz3S2gF+b0fxFDu8U2ks7R8Q9buku64B0pE9Vig= = Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3xxw38s02q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 17:39:56 +0000 (GMT) Received: from pps.filterd (APBLRPPMTA02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 446HdrcU009803; Mon, 6 May 2024 17:39:53 GMT Received: from pps.reinject (localhost [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTPS id 3xwe3k9twq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 17:39:53 +0000 Received: from APBLRPPMTA02.qualcomm.com (APBLRPPMTA02.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446Hdp0G009759; Mon, 6 May 2024 17:39:53 GMT Received: from hu-devc-blr-u22-a.qualcomm.com (hu-hprem-blr.qualcomm.com [10.190.108.75]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTPS id 446Hdqu5009793 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 17:39:53 +0000 Received: by hu-devc-blr-u22-a.qualcomm.com (Postfix, from userid 4146166) id 328E541578; Mon, 6 May 2024 23:09:52 +0530 (+0530) From: Harshitha Prem To: ath12k@lists.infradead.org Cc: linux-wireless@vger.kernel.org, Karthikeyan Periyasamy , Harshitha Prem Subject: [PATCH v3 6/8] wifi: ath12k: Introduce device group abstraction Date: Mon, 6 May 2024 23:09:41 +0530 Message-Id: <20240506173943.1747037-7-quic_hprem@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240506173943.1747037-1-quic_hprem@quicinc.com> References: <20240506173943.1747037-1-quic_hprem@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: WesrP3s0JTqHDLed-J81zlSj_iAgomxc X-Proofpoint-ORIG-GUID: WesrP3s0JTqHDLed-J81zlSj_iAgomxc X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_12,2024-05-06_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 bulkscore=0 clxscore=1015 mlxlogscore=999 priorityscore=1501 lowpriorityscore=0 mlxscore=0 malwarescore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2405060126 From: Karthikeyan Periyasamy 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 would be part of a single wiphy and for this, hardware device group abstraction would be helpful. 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. 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 named ath12k_hw_group (ag) and the following helpers are introduced: ath12k_core_hw_group_alloc() : allocate ath12k_hw_group (ag) based on group id and number of devices that are going to be part of this group. ath12k_core_hw_group_free() : free ag during deinit. ath12k_core_assign_hw_group() : assign/map the details of group to ath12k_base (ab). ath12k_core_unassign_hw_group() : unassign/unmap the details of ag in ath12k_base (ab). ath12k_core_hw_group_create() : create the devices which are part of group (ag). ath12k_core_hw_group_destroy() : cleanup the devices in ag These helpers are used during device probe and mapping the group to the devices involved. Please find the illustration of how multiple devices might be combined together in future based on group id. Grouping of multiple devices (in future) +------------------------------------------------------------------------+ | +-------------------------------------+ +-------------------+ | | | +-----------+ | | +-----------+ | | +-----------+ | | | | | 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.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Karthikeyan Periyasamy Co-developed-by: Harshitha Prem Signed-off-by: Harshitha Prem --- drivers/net/wireless/ath/ath12k/core.c | 218 ++++++++++++++++++++++++- drivers/net/wireless/ath/ath12k/core.h | 19 +++ drivers/net/wireless/ath/ath12k/pci.c | 1 + 3 files changed, 229 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 23b0edec1789..c1cda7d37c1a 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -21,6 +21,9 @@ unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); MODULE_PARM_DESC(debug_mask, "Debugging mask"); +static DEFINE_MUTEX(ath12k_hw_lock); +static struct list_head ath12k_hw_groups = LIST_HEAD_INIT(ath12k_hw_groups); + static int ath12k_core_rfkill_config(struct ath12k_base *ab) { struct ath12k *ar; @@ -1188,20 +1191,111 @@ int ath12k_core_pre_init(struct ath12k_base *ab) return 0; } -int ath12k_core_init(struct ath12k_base *ab) +static inline +bool ath12k_core_hw_group_create_ready(struct ath12k_hw_group *ag) { - int ret; + lockdep_assert_held(&ag->mutex_lock); - ret = ath12k_core_soc_create(ab); - if (ret) { - ath12k_err(ab, "failed to create soc core: %d\n", ret); - return ret; + return (ag->num_probed == ag->num_devices); +} + +static struct ath12k_hw_group * +ath12k_core_hw_group_alloc(u8 id, u8 max_devices) +{ + struct ath12k_hw_group *ag; + + lockdep_assert_held(&ath12k_hw_lock); + + ag = kzalloc(sizeof(*ag), GFP_KERNEL); + if (!ag) + return NULL; + + ag->id = id; + ag->num_devices = max_devices; + list_add(&ag->list, &ath12k_hw_groups); + mutex_init(&ag->mutex_lock); + + return ag; +} + +static void ath12k_core_hw_group_free(struct ath12k_hw_group *ag) +{ + mutex_lock(&ath12k_hw_lock); + + list_del(&ag->list); + kfree(ag); + + mutex_unlock(&ath12k_hw_lock); +} + +static struct ath12k_hw_group *ath12k_core_assign_hw_group(struct ath12k_base *ab) +{ + struct ath12k_hw_group *ag; + u32 group_id = ATH12K_INVALID_GROUP_ID; + + lockdep_assert_held(&ath12k_hw_lock); + + /* The grouping of multiple devices will be done based on device tree file. + * TODO: device tree file parsing to know about the devices involved in group. + * + * The platforms that do not have any valid group information would have each + * device to be part of its own invalid group. + * + * Currently, we are not parsing any device tree information and hence, grouping + * of multiple devices is not involved. Thus, single device is added to device + * group. + */ + ag = ath12k_core_hw_group_alloc(group_id, 1); + if (!ag) { + ath12k_warn(ab, "unable to create new hw group\n"); + return NULL; } + ath12k_dbg(ab, ATH12K_DBG_BOOT, "Single device is added to hardware group\n"); - return 0; + ab->device_id = ag->num_probed++; + ag->ab[ab->device_id] = ab; + ab->ag = ag; + + return ag; } -void ath12k_core_deinit(struct ath12k_base *ab) +void ath12k_core_unassign_hw_group(struct ath12k_base *ab) +{ + struct ath12k_hw_group *ag = ab->ag; + u8 device_id = ab->device_id; + int num_probed; + + if (!ag) + return; + + mutex_lock(&ag->mutex_lock); + + if (WARN_ON(device_id >= ag->num_devices)) { + mutex_unlock(&ag->mutex_lock); + return; + } + + if (WARN_ON(ag->ab[device_id] != ab)) { + mutex_unlock(&ag->mutex_lock); + return; + } + + ag->ab[device_id] = NULL; + ab->ag = NULL; + ab->device_id = ATH12K_INVALID_DEVICE_ID; + + if (ag->num_probed) + ag->num_probed--; + + num_probed = ag->num_probed; + + mutex_unlock(&ag->mutex_lock); + + if (!num_probed) + ath12k_core_hw_group_free(ag); +} + +static void ath12k_core_device_cleanup(struct ath12k_base *ab) { mutex_lock(&ab->core_lock); @@ -1212,8 +1306,114 @@ void ath12k_core_deinit(struct ath12k_base *ab) ath12k_core_stop(ab); mutex_unlock(&ab->core_lock); +} + +static void ath12k_core_hw_group_destroy(struct ath12k_hw_group *ag) +{ + struct ath12k_base *ab; + int i; - ath12k_core_soc_destroy(ab); + if (WARN_ON(!ag)) + return; + + for (i = 0; i < ag->num_devices; i++) { + ab = ag->ab[i]; + if (!ab) + continue; + + if (test_and_clear_bit(ATH12K_FLAG_HW_GROUP_ATTACHED, &ab->dev_flags)) + ath12k_core_soc_destroy(ab); + } +} + +static void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag) +{ + struct ath12k_base *ab; + int i; + + if (!ag) + return; + + mutex_lock(&ag->mutex_lock); + for (i = 0; i < ag->num_devices; i++) { + ab = ag->ab[i]; + if (!ab) + continue; + + if (test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags)) + ath12k_core_device_cleanup(ab); + } + mutex_unlock(&ag->mutex_lock); +} + +static int ath12k_core_hw_group_create(struct ath12k_hw_group *ag) +{ + int i, ret; + struct ath12k_base *ab; + + lockdep_assert_held(&ag->mutex_lock); + + for (i = 0; i < ag->num_devices; i++) { + ab = ag->ab[i]; + if (!ab) + continue; + + mutex_lock(&ab->core_lock); + ret = ath12k_core_soc_create(ab); + if (ret) { + mutex_unlock(&ab->core_lock); + ath12k_err(ab, "failed to create soc core: %d\n", ret); + return ret; + } + set_bit(ATH12K_FLAG_HW_GROUP_ATTACHED, &ab->dev_flags); + mutex_unlock(&ab->core_lock); + } + + return 0; +} + +int ath12k_core_init(struct ath12k_base *ab) +{ + struct ath12k_hw_group *ag; + int ret; + + mutex_lock(&ath12k_hw_lock); + ag = ath12k_core_assign_hw_group(ab); + if (!ag) { + mutex_unlock(&ath12k_hw_lock); + ath12k_warn(ab, "unable to get hw group\n"); + return -ENODEV; + } + mutex_unlock(&ath12k_hw_lock); + + mutex_lock(&ag->mutex_lock); + + ath12k_dbg(ab, ATH12K_DBG_BOOT, "num devices in group %d, num probed %d\n", + ag->num_devices, ag->num_probed); + + if (ath12k_core_hw_group_create_ready(ag)) { + ret = ath12k_core_hw_group_create(ag); + if (ret) { + mutex_unlock(&ag->mutex_lock); + ath12k_warn(ab, "unable to create hw group\n"); + goto err_hw_group; + } + } + mutex_unlock(&ag->mutex_lock); + + return 0; + +err_hw_group: + ath12k_core_hw_group_destroy(ab->ag); + ath12k_core_unassign_hw_group(ab); + return ret; +} + +void ath12k_core_deinit(struct ath12k_base *ab) +{ + ath12k_core_hw_group_cleanup(ab->ag); + ath12k_core_hw_group_destroy(ab->ag); + ath12k_core_unassign_hw_group(ab); } void ath12k_core_free(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 4736d1afa0c7..c6238335c7c0 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -59,6 +59,10 @@ #define ATH12K_RECONFIGURE_TIMEOUT_HZ (10 * HZ) #define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ) +#define ATH12K_MAX_SOCS 3 +#define ATH12K_INVALID_GROUP_ID 0xFF +#define ATH12K_INVALID_DEVICE_ID 0xFF + enum ath12k_bdf_search { ATH12K_BDF_SEARCH_DEFAULT, ATH12K_BDF_SEARCH_BUS_AND_BOARD, @@ -211,6 +215,7 @@ enum ath12k_dev_flags { ATH12K_FLAG_CE_IRQ_ENABLED, ATH12K_FLAG_EXT_IRQ_ENABLED, ATH12K_FLAG_QMI_FW_READY_COMPLETE, + ATH12K_FLAG_HW_GROUP_ATTACHED, }; enum ath12k_monitor_flags { @@ -732,6 +737,17 @@ struct ath12k_soc_dp_stats { struct ath12k_soc_dp_tx_err_stats tx_err; }; +/* Holds info on the group of devices that are registered as a single wiphy */ +struct ath12k_hw_group { + struct list_head list; + u8 id; + u8 num_devices; + u8 num_probed; + struct ath12k_base *ab[ATH12K_MAX_SOCS]; + /* To synchronize group create, assign, start, stop */ + struct mutex mutex_lock; +}; + /** * enum ath12k_link_capable_flags - link capable flags * @@ -932,6 +948,8 @@ struct ath12k_base { #endif /* CONFIG_ACPI */ + struct ath12k_hw_group *ag; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; @@ -962,6 +980,7 @@ int ath12k_core_resume_early(struct ath12k_base *ab); int ath12k_core_resume(struct ath12k_base *ab); int ath12k_core_suspend(struct ath12k_base *ab); int ath12k_core_suspend_late(struct ath12k_base *ab); +void ath12k_core_unassign_hw_group(struct ath12k_base *ab); const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab, const char *filename); diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 95259b8cf251..a4605549ba13 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1505,6 +1505,7 @@ static void ath12k_pci_remove(struct pci_dev *pdev) if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) { ath12k_pci_power_down(ab, false); ath12k_qmi_deinit_service(ab); + ath12k_core_unassign_hw_group(ab); goto qmi_fail; }