Search Linux Wireless

Problem with Kernel Oops in ipw2200

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

after getting this bug
https://bugzilla.novell.com/show_bug.cgi?id=397390
i tried to reproduce this and even got a kernel Oops
in ipw2200 (ipw_tx_skb) after about 15 Minutes pinging
through a wpa enterprise connection.

After some tests i came up with the attaced patch that
fixes the issue for me here, but is probably the wrong
way to go as this is my first attempt in the wireless network
area.
Ever suggestion is very appreciated.

Thanks,
Frank
From: Frank Seidel <fseidel@xxxxxxx>
Subject: fix panic on reauth
Patch-mainline: not yet
References: bnc#397390

This is mainly a rework/partly revocation of the patch
from David S. Miller <davem@xxxxxxxxxxxxx>
commit 521c4d96e0840ecce25b956e00f416ed499ef2ba

Signed-off-by: Frank Seidel <fseidel@xxxxxxx>

---
 drivers/net/wireless/ipw2200.c |   23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -10153,8 +10153,14 @@ static  void init_sys_config(struct ipw_
 
 static int ipw_net_open(struct net_device *dev)
 {
+	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_INFO("dev->open\n");
-	netif_start_queue(dev);
+	/* we should be verifying the device is ready to be opened */
+	mutex_lock(&priv->mutex);
+	if (!(priv->status & STATUS_RF_KILL_MASK) &&
+	    (priv->status & STATUS_ASSOCIATED))
+		netif_start_queue(dev);
+	mutex_unlock(&priv->mutex);
 	return 0;
 }
 
@@ -10474,6 +10480,13 @@ static int ipw_net_hard_start_xmit(struc
 	IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
 	spin_lock_irqsave(&priv->lock, flags);
 
+	if (!(priv->status & STATUS_ASSOCIATED)) {
+		IPW_DEBUG_INFO("Tx attempt while not associated.\n");
+		priv->ieee->stats.tx_carrier_errors++;
+		netif_stop_queue(dev);
+		goto fail_unlock;
+	}
+
 #ifdef CONFIG_IPW2200_PROMISCUOUS
 	if (rtap_iface && netif_running(priv->prom_net_dev))
 		ipw_handle_promiscuous_tx(priv, txb);
@@ -10485,6 +10498,10 @@ static int ipw_net_hard_start_xmit(struc
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return ret;
+
+      fail_unlock:
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return 1;
 }
 
 static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
@@ -10685,6 +10702,10 @@ static void ipw_link_up(struct ipw_priv
 	priv->last_packet_time = 0;
 
 	netif_carrier_on(priv->net_dev);
+	if (netif_queue_stopped(priv->net_dev)) {
+		IPW_DEBUG_NOTIF("waking queue\n");
+		netif_wake_queue(priv->net_dev);
+	}
 
 	cancel_delayed_work(&priv->request_scan);
 	cancel_delayed_work(&priv->request_direct_scan);

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux