aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wimax/i2400m/netdev.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index f67af4291f8c..599aa4eb9baa 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -89,7 +89,10 @@ enum {
89 * The MTU is 1400 or less 89 * The MTU is 1400 or less
90 */ 90 */
91 I2400M_MAX_MTU = 1400, 91 I2400M_MAX_MTU = 1400,
92 I2400M_TX_TIMEOUT = HZ, 92 /* 20 secs? yep, this is the maximum timeout that the device
93 * might take to get out of IDLE / negotiate it with the base
94 * station. We add 1sec for good measure. */
95 I2400M_TX_TIMEOUT = 21 * HZ,
93 I2400M_TX_QLEN = 5, 96 I2400M_TX_QLEN = 5,
94}; 97};
95 98
@@ -151,6 +154,7 @@ void i2400m_wake_tx_work(struct work_struct *ws)
151{ 154{
152 int result; 155 int result;
153 struct i2400m *i2400m = container_of(ws, struct i2400m, wake_tx_ws); 156 struct i2400m *i2400m = container_of(ws, struct i2400m, wake_tx_ws);
157 struct net_device *net_dev = i2400m->wimax_dev.net_dev;
154 struct device *dev = i2400m_dev(i2400m); 158 struct device *dev = i2400m_dev(i2400m);
155 struct sk_buff *skb = i2400m->wake_tx_skb; 159 struct sk_buff *skb = i2400m->wake_tx_skb;
156 unsigned long flags; 160 unsigned long flags;
@@ -166,6 +170,11 @@ void i2400m_wake_tx_work(struct work_struct *ws)
166 dev_err(dev, "WAKE&TX: skb dissapeared!\n"); 170 dev_err(dev, "WAKE&TX: skb dissapeared!\n");
167 goto out_put; 171 goto out_put;
168 } 172 }
173 /* If we have, somehow, lost the connection after this was
174 * queued, don't do anything; this might be the device got
175 * reset or just disconnected. */
176 if (unlikely(!netif_carrier_ok(net_dev)))
177 goto out_kfree;
169 result = i2400m_cmd_exit_idle(i2400m); 178 result = i2400m_cmd_exit_idle(i2400m);
170 if (result == -EILSEQ) 179 if (result == -EILSEQ)
171 result = 0; 180 result = 0;
@@ -176,7 +185,8 @@ void i2400m_wake_tx_work(struct work_struct *ws)
176 goto error; 185 goto error;
177 } 186 }
178 result = wait_event_timeout(i2400m->state_wq, 187 result = wait_event_timeout(i2400m->state_wq,
179 i2400m->state != I2400M_SS_IDLE, 5 * HZ); 188 i2400m->state != I2400M_SS_IDLE,
189 net_dev->watchdog_timeo - HZ/2);
180 if (result == 0) 190 if (result == 0)
181 result = -ETIMEDOUT; 191 result = -ETIMEDOUT;
182 if (result < 0) { 192 if (result < 0) {
@@ -187,8 +197,9 @@ void i2400m_wake_tx_work(struct work_struct *ws)
187 } 197 }
188 msleep(20); /* device still needs some time or it drops it */ 198 msleep(20); /* device still needs some time or it drops it */
189 result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA); 199 result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA);
190 netif_wake_queue(i2400m->wimax_dev.net_dev);
191error: 200error:
201 netif_wake_queue(net_dev);
202out_kfree:
192 kfree_skb(skb); /* refcount transferred by _hard_start_xmit() */ 203 kfree_skb(skb); /* refcount transferred by _hard_start_xmit() */
193out_put: 204out_put:
194 i2400m_put(i2400m); 205 i2400m_put(i2400m);