From f7f428e4622fb1e590cde93790f978f3ff0e69ae Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Tue, 3 Aug 2010 17:28:28 +0800 Subject: [PATCH] [jme] Protect vlgrp structure by pause RX actions. --- jme.c | 39 +++++++++++++++++++++++++++++++++------ jme.h | 1 - 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/jme.c b/jme.c index 9096bbd..c0b59a5 100644 --- a/jme.c +++ b/jme.c @@ -942,14 +942,11 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) skb->ip_summed = CHECKSUM_NONE; if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { - spin_lock(&jme->vlgrp_lock); if (jme->vlgrp) { jme->jme_vlan_rx(skb, jme->vlgrp, le16_to_cpu(rxdesc->descwb.vlan)); - spin_unlock(&jme->vlgrp_lock); NET_STAT(jme).rx_bytes += 4; } else { - spin_unlock(&jme->vlgrp_lock); dev_kfree_skb(skb); } } else { @@ -2086,14 +2083,45 @@ jme_tx_timeout(struct net_device *netdev) jme_reset_link(jme); } +static inline void jme_pause_rx(struct jme_adapter *jme) +{ + atomic_dec(&jme->link_changing); + + jme_set_rx_pcc(jme, PCC_OFF); + if (test_bit(JME_FLAG_POLL, &jme->flags)) { + JME_NAPI_DISABLE(jme); + } else { + tasklet_disable(&jme->rxclean_task); + tasklet_disable(&jme->rxempty_task); + } +} + +static inline void jme_resume_rx(struct jme_adapter *jme) +{ + struct dynpcc_info *dpi = &(jme->dpi); + + if (test_bit(JME_FLAG_POLL, &jme->flags)) { + JME_NAPI_ENABLE(jme); + } else { + tasklet_hi_enable(&jme->rxclean_task); + tasklet_hi_enable(&jme->rxempty_task); + } + dpi->cur = PCC_P1; + dpi->attempt = PCC_P1; + dpi->cnt = 0; + jme_set_rx_pcc(jme, PCC_P1); + + atomic_inc(&jme->link_changing); +} + static void jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { struct jme_adapter *jme = netdev_priv(netdev); - spin_lock_bh(&jme->vlgrp_lock); + jme_pause_rx(jme); jme->vlgrp = grp; - spin_unlock_bh(&jme->vlgrp_lock); + jme_resume_rx(jme); } static void @@ -2760,7 +2788,6 @@ jme_init_one(struct pci_dev *pdev, spin_lock_init(&jme->phy_lock); spin_lock_init(&jme->macaddr_lock); spin_lock_init(&jme->rxmcs_lock); - spin_lock_init(&jme->vlgrp_lock); atomic_set(&jme->link_changing, 1); atomic_set(&jme->rx_cleaning, 1); diff --git a/jme.h b/jme.h index 727a3bf..07ad3a4 100644 --- a/jme.h +++ b/jme.h @@ -393,7 +393,6 @@ struct jme_adapter { spinlock_t phy_lock; spinlock_t macaddr_lock; spinlock_t rxmcs_lock; - spinlock_t vlgrp_lock; struct tasklet_struct rxempty_task; struct tasklet_struct rxclean_task; struct tasklet_struct txclean_task; -- 2.39.3