From 35eae45f4e9437c081059002ca375cf444f11733 Mon Sep 17 00:00:00 2001 From: Asutosh Mohapatra Date: Wed, 21 May 2025 03:29:12 -0700 Subject: [PATCH] qcacld-3.0: Handling Dummy Netdev Allocation in Kernel 6.13+ With the introduction of kernel version 6.13, the init_dummy_netdev symbol has been made static and is no longer exported. Consequently, drivers must now utilize alloc_netdev_dummy() to allocate and initialize dummy network devices. The current implementation defines the net_device structure as a static instance within the driver. However, since alloc_netdev_dummy() dynamically allocates and initializes the dummy netdev, assigning its return value to a statically defined structure is incorrect and leads to undefined behavior. To address this, a pointer to a net_device structure should be added to the host context. The driver should store the pointer returned by alloc_netdev_dummy() in this new member. Additionally, appropriate cleanup logic must be implemented to free the allocated dummy netdev during driver teardown. Change-Id: I8eda57fd3ece411579f2d3eb2f1249c2905bbeac CRs-Fixed: 4158431 --- components/dp/core/inc/wlan_dp_rx_thread.h | 6 +++- components/dp/core/src/wlan_dp_rx_thread.c | 35 ++++++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/components/dp/core/inc/wlan_dp_rx_thread.h b/components/dp/core/inc/wlan_dp_rx_thread.h index 75b7e84f18..24324b63e7 100644 --- a/components/dp/core/inc/wlan_dp_rx_thread.h +++ b/components/dp/core/inc/wlan_dp_rx_thread.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -141,7 +141,11 @@ struct dp_rx_thread { struct dp_rx_tm_handle_cmn *rtm_handle_cmn; qdf_napi_struct napi; qdf_wait_queue_head_t wait_q; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) + qdf_dummy_netdev_t *netdev; +#else qdf_dummy_netdev_t netdev; +#endif qdf_netdev_t net_dev[WLAN_PDEV_MAX_VDEVS]; }; diff --git a/components/dp/core/src/wlan_dp_rx_thread.c b/components/dp/core/src/wlan_dp_rx_thread.c index d7a24ad9bc..a56e9f06d0 100644 --- a/components/dp/core/src/wlan_dp_rx_thread.c +++ b/components/dp/core/src/wlan_dp_rx_thread.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -836,6 +836,27 @@ static int dp_rx_tm_thread_napi_poll(qdf_napi_struct *napi, int budget) return 0; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +/** + * dp_rx_thread_get_dummy_netdev_ptr() - Get dummy netdev pointer + * fromdp rx thread + * @rx_thread: DP RX thread pointer + * + * Return: dummy netdev pointer + */ +static inline struct net_device * +dp_rx_thread_get_dummy_netdev_ptr(struct dp_rx_thread *rx_thread) +{ + return rx_thread->netdev; +} +#else +static inline struct net_device * +dp_rx_thread_get_dummy_netdev_ptr(struct dp_rx_thread *rx_thread) +{ + return &rx_thread->netdev; +} +#endif + /** * dp_rx_tm_thread_napi_init() - Initialize dummy rx_thread NAPI * @rx_thread: dp_rx_thread structure containing dummy napi and netdev @@ -844,9 +865,12 @@ static int dp_rx_tm_thread_napi_poll(qdf_napi_struct *napi, int budget) */ static void dp_rx_tm_thread_napi_init(struct dp_rx_thread *rx_thread) { + struct net_device *dummy_nd; + + dummy_nd = dp_rx_thread_get_dummy_netdev_ptr(rx_thread); /* Todo - optimize to use only one dummy netdev for all thread napis */ - qdf_net_if_create_dummy_if((struct qdf_net_if *)&rx_thread->netdev); - qdf_netif_napi_add(&rx_thread->netdev, &rx_thread->napi, + qdf_net_if_create_dummy_if((struct qdf_net_if **)&dummy_nd); + qdf_netif_napi_add(dummy_nd, &rx_thread->napi, dp_rx_tm_thread_napi_poll, 64); qdf_napi_enable(&rx_thread->napi); } @@ -859,6 +883,11 @@ static void dp_rx_tm_thread_napi_init(struct dp_rx_thread *rx_thread) */ static void dp_rx_tm_thread_napi_deinit(struct dp_rx_thread *rx_thread) { + struct net_device *dummy_nd; + + dummy_nd = dp_rx_thread_get_dummy_netdev_ptr(rx_thread); + qdf_net_if_destroy_dummy_if((struct qdf_net_if *)dummy_nd); + qdf_netif_napi_del(&rx_thread->napi); }