dataipa: make raw notifier generic to multiple clients

Make buffer threshold raw notifier generic to multiple clients.

Change-Id: I99e7e57c0e9388b01c338cb5f6424481995b0924
Signed-off-by: Michael Adisumarta <quic_madisuma@quicinc.com>
This commit is contained in:
Michael Adisumarta
2023-01-30 13:49:31 -08:00
parent 910a63643e
commit 7ae7eaca59
2 changed files with 34 additions and 20 deletions

View File

@@ -3,7 +3,7 @@
/* /*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* *
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
@@ -2865,21 +2865,22 @@ static struct ipa3_rx_pkt_wrapper * ipa3_get_free_page
int ipa_register_notifier(void *fn_ptr) int ipa_register_notifier(void *fn_ptr)
{ {
struct ipa_notifier_block_data *ipa_notifier_block;
if (fn_ptr == NULL) if (fn_ptr == NULL)
return -EFAULT; return -EFAULT;
spin_lock(&ipa3_ctx->notifier_lock); spin_lock(&ipa3_ctx->notifier_lock);
atomic_set(&ipa3_ctx->stats.num_buff_above_thresh_for_def_pipe_notified, 0); ipa_notifier_block = (struct ipa_notifier_block_data *)kzalloc(sizeof(struct ipa_notifier_block_data), GFP_KERNEL);
atomic_set(&ipa3_ctx->stats.num_buff_above_thresh_for_coal_pipe_notified, 0); if (ipa_notifier_block == NULL) {
atomic_set(&ipa3_ctx->stats.num_buff_below_thresh_for_def_pipe_notified, 0); IPAWANERR("Buffer threshold notifier failure\n");
atomic_set(&ipa3_ctx->stats.num_buff_below_thresh_for_coal_pipe_notified, 0); spin_unlock(&ipa3_ctx->notifier_lock);
ipa3_ctx->ipa_rmnet_notifier.notifier_call = fn_ptr; return -EFAULT;
if (!ipa3_ctx->ipa_rmnet_notifier_enabled)
raw_notifier_chain_register(ipa3_ctx->ipa_rmnet_notifier_list_internal,
&ipa3_ctx->ipa_rmnet_notifier);
else {
IPAWANERR("rcvd notifier reg again, changing the cb function\n");
ipa3_ctx->ipa_rmnet_notifier.notifier_call = fn_ptr;
} }
ipa_notifier_block->ipa_rmnet_notifier.notifier_call = fn_ptr;
list_add(&ipa_notifier_block->entry, &ipa3_ctx->notifier_block_list_head);
raw_notifier_chain_register(ipa3_ctx->ipa_rmnet_notifier_list_internal,
&ipa_notifier_block->ipa_rmnet_notifier);
IPAWANERR("Registered noifier for buffer threshold\n");
ipa3_ctx->ipa_rmnet_notifier_enabled = true; ipa3_ctx->ipa_rmnet_notifier_enabled = true;
spin_unlock(&ipa3_ctx->notifier_lock); spin_unlock(&ipa3_ctx->notifier_lock);
return 0; return 0;
@@ -2888,16 +2889,24 @@ EXPORT_SYMBOL(ipa_register_notifier);
int ipa_unregister_notifier(void *fn_ptr) int ipa_unregister_notifier(void *fn_ptr)
{ {
struct ipa_notifier_block_data *ipa_notifier_block, *temp;
if (fn_ptr == NULL) if (fn_ptr == NULL)
return -EFAULT; return -EFAULT;
spin_lock(&ipa3_ctx->notifier_lock); spin_lock(&ipa3_ctx->notifier_lock);
ipa3_ctx->ipa_rmnet_notifier.notifier_call = fn_ptr; /* Find the client pointer, unregister and remove from the list */
if (ipa3_ctx->ipa_rmnet_notifier_enabled) list_for_each_entry_safe(ipa_notifier_block, temp, &ipa3_ctx->notifier_block_list_head, entry) {
raw_notifier_chain_unregister(ipa3_ctx->ipa_rmnet_notifier_list_internal, if (ipa_notifier_block->ipa_rmnet_notifier.notifier_call == fn_ptr) {
&ipa3_ctx->ipa_rmnet_notifier); raw_notifier_chain_unregister(ipa3_ctx->ipa_rmnet_notifier_list_internal,
else IPAWANERR("rcvd notifier unreg again\n"); &ipa_notifier_block->ipa_rmnet_notifier);
ipa3_ctx->ipa_rmnet_notifier_enabled = false; list_del(&ipa_notifier_block->entry);
kfree(ipa_notifier_block);
IPAWANERR("Client removed from list and unregistered succesfully\n");
spin_unlock(&ipa3_ctx->notifier_lock);
return 0;
}
}
spin_unlock(&ipa3_ctx->notifier_lock); spin_unlock(&ipa3_ctx->notifier_lock);
IPAWANERR("Unable to find the client in the list\n");
return 0; return 0;
} }
EXPORT_SYMBOL(ipa_unregister_notifier); EXPORT_SYMBOL(ipa_unregister_notifier);

View File

@@ -2,7 +2,7 @@
/* /*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* *
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _IPA3_I_H_ #ifndef _IPA3_I_H_
@@ -2122,6 +2122,11 @@ struct ipa_minidump_data {
}; };
#endif #endif
struct ipa_notifier_block_data {
struct list_head entry;
struct notifier_block ipa_rmnet_notifier;
};
/* Peripheral stats for Q6, should be in the same order, defined by Q6 */ /* Peripheral stats for Q6, should be in the same order, defined by Q6 */
enum ipa_per_stats_type_e { enum ipa_per_stats_type_e {
IPA_PER_STATS_TYPE_NUM_PERS, IPA_PER_STATS_TYPE_NUM_PERS,
@@ -2564,7 +2569,7 @@ struct ipa3_context {
u64 gsi_msi_addr; u64 gsi_msi_addr;
spinlock_t notifier_lock; spinlock_t notifier_lock;
struct raw_notifier_head *ipa_rmnet_notifier_list_internal; struct raw_notifier_head *ipa_rmnet_notifier_list_internal;
struct notifier_block ipa_rmnet_notifier; struct list_head notifier_block_list_head;
bool ipa_rmnet_notifier_enabled; bool ipa_rmnet_notifier_enabled;
bool buff_above_thresh_for_def_pipe_notified; bool buff_above_thresh_for_def_pipe_notified;
bool buff_above_thresh_for_coal_pipe_notified; bool buff_above_thresh_for_coal_pipe_notified;