ipw2200: fix netif_*_queue() removal regression
authorZhu Yi <yi.zhu@intel.com>
Thu, 27 Nov 2008 05:42:20 +0000 (13:42 +0800)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 5 Dec 2008 14:18:35 +0000 (09:18 -0500)
In "ipw2200: Call netif_*_queue() interfaces properly", netif_stop_queue()
and netif_wake_queue() were removed with the reason
"netif_carrier_{on,off}() handles starting and stopping packet flow into
the driver". The patch also removes a valid condition check that
ipw_tx_skb() cannot be called if device is not in STATUS_ASSOCIATED state.
But netif_carrier_off() doesn't guarantee netdev->hard_start_xmit won't
be called because linkwatch event is handled in a delayed workqueue. This
caused a kernel oops reported by Frank Seidel:
https://bugzilla.novell.com/show_bug.cgi?id=397390

This patch fixes the problem by moving the STATUS_ASSOCIATED check back
to ipw_tx_skb(). It also adds a missing netif_carrier_off() call to
ipw_disassociate().

Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Chatre, Reinette <reinette.chatre@intel.com>
Tested-by: Frank Seidel <fseidel@suse.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ipw2200.c

index dcce3542d5a771d9eb24753d8d464854bb4e6639..7a9f901d4ff6dee5cf15ae78d0f9bb763344bdd7 100644 (file)
@@ -3897,6 +3897,7 @@ static int ipw_disassociate(void *data)
        if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
                return 0;
        ipw_send_disassociate(data, 0);
+       netif_carrier_off(priv->net_dev);
        return 1;
 }
 
@@ -10190,6 +10191,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
        u16 remaining_bytes;
        int fc;
 
+       if (!(priv->status & STATUS_ASSOCIATED))
+               goto drop;
+
        hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
        switch (priv->ieee->iw_mode) {
        case IW_MODE_ADHOC: