msm: rmnet: Use separate tasklet for each rmnet instance
If multiple RMNET devices are active at the same time, there is a data
collision issue for the single tasklet structure that could result in
losing SMD receive events.
Add a dedicated receive tasklet structure for each RMNET instance.
CRs-Fixed: 425114
Change-Id: I160195fd2a002b9c6f47b4b29fd0af355482a3b5
Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org>
diff --git a/drivers/net/ethernet/msm/msm_rmnet.c b/drivers/net/ethernet/msm/msm_rmnet.c
index 4af2d8c..cc9ed74 100644
--- a/drivers/net/ethernet/msm/msm_rmnet.c
+++ b/drivers/net/ethernet/msm/msm_rmnet.c
@@ -94,6 +94,7 @@
struct sk_buff *skb;
spinlock_t lock;
struct tasklet_struct tsklt;
+ struct tasklet_struct rx_tasklet;
u32 operation_mode; /* IOCTL specified mode (protocol, QoS header) */
struct platform_driver pdrv;
struct completion complete;
@@ -257,7 +258,6 @@
}
static void smd_net_data_handler(unsigned long arg);
-static DECLARE_TASKLET(smd_net_data_tasklet, smd_net_data_handler, 0);
/* Called in soft-irq context */
static void smd_net_data_handler(unsigned long arg)
@@ -280,8 +280,8 @@
pr_err("[%s] rmnet_recv() cannot allocate skb\n",
dev->name);
/* out of memory, reschedule a later attempt */
- smd_net_data_tasklet.data = (unsigned long)dev;
- tasklet_schedule(&smd_net_data_tasklet);
+ p->rx_tasklet.data = (unsigned long)dev;
+ tasklet_schedule(&p->rx_tasklet);
break;
} else {
skb->dev = dev;
@@ -449,8 +449,8 @@
if (smd_read_avail(p->ch) &&
(smd_read_avail(p->ch) >= smd_cur_packet_size(p->ch))) {
- smd_net_data_tasklet.data = (unsigned long) _dev;
- tasklet_schedule(&smd_net_data_tasklet);
+ p->rx_tasklet.data = (unsigned long) _dev;
+ tasklet_schedule(&p->rx_tasklet);
}
break;
@@ -788,6 +788,8 @@
spin_lock_init(&p->lock);
tasklet_init(&p->tsklt, _rmnet_resume_flow,
(unsigned long)dev);
+ tasklet_init(&p->rx_tasklet, smd_net_data_handler,
+ (unsigned long)dev);
wake_lock_init(&p->wake_lock, WAKE_LOCK_SUSPEND, ch_name[n]);
#ifdef CONFIG_MSM_RMNET_DEBUG
p->timeout_us = timeout_us;