diff options
author | Guo-Fu Tseng <cooldavid@cooldavid.org> | 2010-03-17 00:09:30 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-04-01 15:58:39 -0700 |
commit | a72fce06535457d953da1ee7d9ef9773c5925fd0 (patch) | |
tree | fed4dd2dba7e27042aac2dca680af976bfbd7e0f /drivers | |
parent | 7aa5e834a22b77dc16a992e8af54514021f05744 (diff) |
jme: Protect vlgrp structure by pause RX actions.
commit bf5e5360fd1df1ae429ebbd81838d7d0879797d1 upstream.
Temporary stop the RX IRQ, and disable (sync) tasklet or napi.
And restore it after finished the vlgrp pointer assignment.
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/jme.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 577cae69f1cf..3bb3a6da36c2 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2087,12 +2087,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); + jme_pause_rx(jme); jme->vlgrp = grp; + jme_resume_rx(jme); } static void |