aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-02 01:08:51 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-02 01:08:51 -0400
commite9e80ea5f2129e135e3a6fa260314b1c6d99b19a (patch)
treedb20dc85b0e620ea3fcaf86a9026d6df7cb2e168 /net
parent2b12a4c524812fb3f6ee590a02e65b95c8c32229 (diff)
parent56decd3c5758b0d776c073f65f777beb7a05ac0a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/tx.c17
-rw-r--r--net/mac80211/util.c1
-rw-r--r--net/rfkill/rfkill-input.c54
-rw-r--r--net/rfkill/rfkill.c15
5 files changed, 67 insertions, 21 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a4f9a832722a..a2e200f9811e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -586,6 +586,7 @@ struct ieee80211_local {
586 struct timer_list sta_cleanup; 586 struct timer_list sta_cleanup;
587 587
588 unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)]; 588 unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
589 unsigned long queues_pending_run[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
589 struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES]; 590 struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES];
590 struct tasklet_struct tx_pending_tasklet; 591 struct tasklet_struct tx_pending_tasklet;
591 592
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 69019e943873..771ec68b848d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1060,13 +1060,14 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1060static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, 1060static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1061 struct ieee80211_tx_data *tx) 1061 struct ieee80211_tx_data *tx)
1062{ 1062{
1063 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1063 struct ieee80211_tx_info *info;
1064 int ret, i; 1064 int ret, i;
1065 1065
1066 if (netif_subqueue_stopped(local->mdev, skb))
1067 return IEEE80211_TX_AGAIN;
1068
1069 if (skb) { 1066 if (skb) {
1067 if (netif_subqueue_stopped(local->mdev, skb))
1068 return IEEE80211_TX_AGAIN;
1069 info = IEEE80211_SKB_CB(skb);
1070
1070 ieee80211_dump_frame(wiphy_name(local->hw.wiphy), 1071 ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
1071 "TX to low-level driver", skb); 1072 "TX to low-level driver", skb);
1072 ret = local->ops->tx(local_to_hw(local), skb); 1073 ret = local->ops->tx(local_to_hw(local), skb);
@@ -1215,6 +1216,7 @@ retry:
1215 1216
1216 if (ret == IEEE80211_TX_FRAG_AGAIN) 1217 if (ret == IEEE80211_TX_FRAG_AGAIN)
1217 skb = NULL; 1218 skb = NULL;
1219
1218 set_bit(queue, local->queues_pending); 1220 set_bit(queue, local->queues_pending);
1219 smp_mb(); 1221 smp_mb();
1220 /* 1222 /*
@@ -1708,14 +1710,19 @@ void ieee80211_tx_pending(unsigned long data)
1708 netif_tx_lock_bh(dev); 1710 netif_tx_lock_bh(dev);
1709 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { 1711 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
1710 /* Check that this queue is ok */ 1712 /* Check that this queue is ok */
1711 if (__netif_subqueue_stopped(local->mdev, i)) 1713 if (__netif_subqueue_stopped(local->mdev, i) &&
1714 !test_bit(i, local->queues_pending_run))
1712 continue; 1715 continue;
1713 1716
1714 if (!test_bit(i, local->queues_pending)) { 1717 if (!test_bit(i, local->queues_pending)) {
1718 clear_bit(i, local->queues_pending_run);
1715 ieee80211_wake_queue(&local->hw, i); 1719 ieee80211_wake_queue(&local->hw, i);
1716 continue; 1720 continue;
1717 } 1721 }
1718 1722
1723 clear_bit(i, local->queues_pending_run);
1724 netif_start_subqueue(local->mdev, i);
1725
1719 store = &local->pending_packet[i]; 1726 store = &local->pending_packet[i];
1720 tx.extra_frag = store->extra_frag; 1727 tx.extra_frag = store->extra_frag;
1721 tx.num_extra_frag = store->num_extra_frag; 1728 tx.num_extra_frag = store->num_extra_frag;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 19f85e1b3695..0d463c80c404 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -361,6 +361,7 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
361 struct ieee80211_local *local = hw_to_local(hw); 361 struct ieee80211_local *local = hw_to_local(hw);
362 362
363 if (test_bit(queue, local->queues_pending)) { 363 if (test_bit(queue, local->queues_pending)) {
364 set_bit(queue, local->queues_pending_run);
364 tasklet_schedule(&local->tx_pending_tasklet); 365 tasklet_schedule(&local->tx_pending_tasklet);
365 } else { 366 } else {
366 netif_wake_subqueue(local->mdev, queue); 367 netif_wake_subqueue(local->mdev, queue);
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 8aa822730145..e5b69556bb5b 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -109,6 +109,25 @@ static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
109static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); 109static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
110static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN); 110static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
111 111
112static void rfkill_schedule_evsw_rfkillall(int state)
113{
114 /* EVERY radio type. state != 0 means radios ON */
115 /* handle EPO (emergency power off) through shortcut */
116 if (state) {
117 rfkill_schedule_set(&rfkill_wwan,
118 RFKILL_STATE_UNBLOCKED);
119 rfkill_schedule_set(&rfkill_wimax,
120 RFKILL_STATE_UNBLOCKED);
121 rfkill_schedule_set(&rfkill_uwb,
122 RFKILL_STATE_UNBLOCKED);
123 rfkill_schedule_set(&rfkill_bt,
124 RFKILL_STATE_UNBLOCKED);
125 rfkill_schedule_set(&rfkill_wlan,
126 RFKILL_STATE_UNBLOCKED);
127 } else
128 rfkill_schedule_epo();
129}
130
112static void rfkill_event(struct input_handle *handle, unsigned int type, 131static void rfkill_event(struct input_handle *handle, unsigned int type,
113 unsigned int code, int data) 132 unsigned int code, int data)
114{ 133{
@@ -132,21 +151,7 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
132 } else if (type == EV_SW) { 151 } else if (type == EV_SW) {
133 switch (code) { 152 switch (code) {
134 case SW_RFKILL_ALL: 153 case SW_RFKILL_ALL:
135 /* EVERY radio type. data != 0 means radios ON */ 154 rfkill_schedule_evsw_rfkillall(data);
136 /* handle EPO (emergency power off) through shortcut */
137 if (data) {
138 rfkill_schedule_set(&rfkill_wwan,
139 RFKILL_STATE_UNBLOCKED);
140 rfkill_schedule_set(&rfkill_wimax,
141 RFKILL_STATE_UNBLOCKED);
142 rfkill_schedule_set(&rfkill_uwb,
143 RFKILL_STATE_UNBLOCKED);
144 rfkill_schedule_set(&rfkill_bt,
145 RFKILL_STATE_UNBLOCKED);
146 rfkill_schedule_set(&rfkill_wlan,
147 RFKILL_STATE_UNBLOCKED);
148 } else
149 rfkill_schedule_epo();
150 break; 155 break;
151 default: 156 default:
152 break; 157 break;
@@ -168,6 +173,7 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
168 handle->handler = handler; 173 handle->handler = handler;
169 handle->name = "rfkill"; 174 handle->name = "rfkill";
170 175
176 /* causes rfkill_start() to be called */
171 error = input_register_handle(handle); 177 error = input_register_handle(handle);
172 if (error) 178 if (error)
173 goto err_free_handle; 179 goto err_free_handle;
@@ -185,6 +191,23 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
185 return error; 191 return error;
186} 192}
187 193
194static void rfkill_start(struct input_handle *handle)
195{
196 /* Take event_lock to guard against configuration changes, we
197 * should be able to deal with concurrency with rfkill_event()
198 * just fine (which event_lock will also avoid). */
199 spin_lock_irq(&handle->dev->event_lock);
200
201 if (test_bit(EV_SW, handle->dev->evbit)) {
202 if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))
203 rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
204 handle->dev->sw));
205 /* add resync for further EV_SW events here */
206 }
207
208 spin_unlock_irq(&handle->dev->event_lock);
209}
210
188static void rfkill_disconnect(struct input_handle *handle) 211static void rfkill_disconnect(struct input_handle *handle)
189{ 212{
190 input_close_device(handle); 213 input_close_device(handle);
@@ -225,6 +248,7 @@ static struct input_handler rfkill_handler = {
225 .event = rfkill_event, 248 .event = rfkill_event,
226 .connect = rfkill_connect, 249 .connect = rfkill_connect,
227 .disconnect = rfkill_disconnect, 250 .disconnect = rfkill_disconnect,
251 .start = rfkill_start,
228 .name = "rfkill", 252 .name = "rfkill",
229 .id_table = rfkill_ids, 253 .id_table = rfkill_ids,
230}; 254};
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index c6f2f388cb72..d2d45655cd1a 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -105,6 +105,16 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
105#endif /* CONFIG_RFKILL_LEDS */ 105#endif /* CONFIG_RFKILL_LEDS */
106} 106}
107 107
108#ifdef CONFIG_RFKILL_LEDS
109static void rfkill_led_trigger_activate(struct led_classdev *led)
110{
111 struct rfkill *rfkill = container_of(led->trigger,
112 struct rfkill, led_trigger);
113
114 rfkill_led_trigger(rfkill, rfkill->state);
115}
116#endif /* CONFIG_RFKILL_LEDS */
117
108static void notify_rfkill_state_change(struct rfkill *rfkill) 118static void notify_rfkill_state_change(struct rfkill *rfkill)
109{ 119{
110 blocking_notifier_call_chain(&rfkill_notifier_list, 120 blocking_notifier_call_chain(&rfkill_notifier_list,
@@ -589,7 +599,10 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill)
589#ifdef CONFIG_RFKILL_LEDS 599#ifdef CONFIG_RFKILL_LEDS
590 int error; 600 int error;
591 601
592 rfkill->led_trigger.name = rfkill->dev.bus_id; 602 if (!rfkill->led_trigger.name)
603 rfkill->led_trigger.name = rfkill->dev.bus_id;
604 if (!rfkill->led_trigger.activate)
605 rfkill->led_trigger.activate = rfkill_led_trigger_activate;
593 error = led_trigger_register(&rfkill->led_trigger); 606 error = led_trigger_register(&rfkill->led_trigger);
594 if (error) 607 if (error)
595 rfkill->led_trigger.name = NULL; 608 rfkill->led_trigger.name = NULL;