aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorRoland Vossen <rvossen@broadcom.com>2011-10-12 14:51:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-10-14 14:48:16 -0400
commit2a7fc5b1c17a6055fe2753ebacaf43b5780bcf99 (patch)
treebae75a98fea99de15a4b38b4d6386596a820ecd3 /drivers/net/wireless/brcm80211
parentbe69c4ef462a476523f89c74e7db29f6ad207a1a (diff)
brcm80211: smac: decreased timer callback irq level
Timer functions were called at soft-irq level, leading to the limitation that mutexes could not be used. Lifted this limitation by migrating to work queues. Reviewed-by: Alwin Beukers <alwin@broadcom.com> Reviewed-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c40
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h12
2 files changed, 24 insertions, 28 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index b665aafe19a..6ce773aee6c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1409,18 +1409,22 @@ void brcms_down(struct brcms_info *wl)
1409/* 1409/*
1410* precondition: perimeter lock is not acquired 1410* precondition: perimeter lock is not acquired
1411 */ 1411 */
1412void brcms_timer(struct brcms_timer *t) 1412static void _brcms_timer(struct work_struct *work)
1413{ 1413{
1414 struct brcms_timer *t = container_of(work, struct brcms_timer,
1415 dly_wrk.work);
1416
1414 spin_lock_bh(&t->wl->lock); 1417 spin_lock_bh(&t->wl->lock);
1415 1418
1416 if (t->set) { 1419 if (t->set) {
1417 if (t->periodic) { 1420 if (t->periodic) {
1418 t->timer.expires = jiffies + t->ms * HZ / 1000;
1419 atomic_inc(&t->wl->callbacks); 1421 atomic_inc(&t->wl->callbacks);
1420 add_timer(&t->timer); 1422 ieee80211_queue_delayed_work(t->wl->pub->ieee_hw,
1421 t->set = true; 1423 &t->dly_wrk,
1422 } else 1424 msecs_to_jiffies(t->ms));
1425 } else {
1423 t->set = false; 1426 t->set = false;
1427 }
1424 1428
1425 t->fn(t->arg); 1429 t->fn(t->arg);
1426 } 1430 }
@@ -1431,14 +1435,6 @@ void brcms_timer(struct brcms_timer *t)
1431} 1435}
1432 1436
1433/* 1437/*
1434 * is called by the kernel from software irq context
1435 */
1436static void _brcms_timer(unsigned long data)
1437{
1438 brcms_timer((struct brcms_timer *) data);
1439}
1440
1441/*
1442 * Adds a timer to the list. Caller supplies a timer function. 1438 * Adds a timer to the list. Caller supplies a timer function.
1443 * Is called from wlc. 1439 * Is called from wlc.
1444 * 1440 *
@@ -1454,9 +1450,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
1454 if (!t) 1450 if (!t)
1455 return NULL; 1451 return NULL;
1456 1452
1457 init_timer(&t->timer); 1453 INIT_DELAYED_WORK(&t->dly_wrk, _brcms_timer);
1458 t->timer.data = (unsigned long) t;
1459 t->timer.function = _brcms_timer;
1460 t->wl = wl; 1454 t->wl = wl;
1461 t->fn = fn; 1455 t->fn = fn;
1462 t->arg = arg; 1456 t->arg = arg;
@@ -1478,22 +1472,22 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
1478 * 1472 *
1479 * precondition: perimeter lock has been acquired 1473 * precondition: perimeter lock has been acquired
1480 */ 1474 */
1481void brcms_add_timer(struct brcms_timer *t, uint ms, 1475void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
1482 int periodic)
1483{ 1476{
1477 struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
1478
1484#ifdef BCMDBG 1479#ifdef BCMDBG
1485 if (t->set) 1480 if (t->set)
1486 wiphy_err(t->wl->wiphy, "%s: Already set. Name: %s, per %d\n", 1481 wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
1487 __func__, t->name, periodic); 1482 __func__, t->name, periodic);
1488
1489#endif 1483#endif
1490 t->ms = ms; 1484 t->ms = ms;
1491 t->periodic = (bool) periodic; 1485 t->periodic = (bool) periodic;
1492 t->set = true; 1486 t->set = true;
1493 t->timer.expires = jiffies + ms * HZ / 1000;
1494 1487
1495 atomic_inc(&t->wl->callbacks); 1488 atomic_inc(&t->wl->callbacks);
1496 add_timer(&t->timer); 1489
1490 ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
1497} 1491}
1498 1492
1499/* 1493/*
@@ -1505,7 +1499,7 @@ bool brcms_del_timer(struct brcms_timer *t)
1505{ 1499{
1506 if (t->set) { 1500 if (t->set) {
1507 t->set = false; 1501 t->set = false;
1508 if (!del_timer(&t->timer)) 1502 if (!cancel_delayed_work(&t->dly_wrk))
1509 return false; 1503 return false;
1510 1504
1511 atomic_dec(&t->wl->callbacks); 1505 atomic_dec(&t->wl->callbacks);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
index 91e5f2ac56c..177f0e44e4b 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -19,6 +19,8 @@
19 19
20#include <linux/timer.h> 20#include <linux/timer.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/workqueue.h>
23
22#include "ucode_loader.h" 24#include "ucode_loader.h"
23/* 25/*
24 * Starting index for 5G rates in the 26 * Starting index for 5G rates in the
@@ -30,14 +32,14 @@
30#define BRCMS_SET_SHORTSLOT_OVERRIDE 146 32#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
31 33
32struct brcms_timer { 34struct brcms_timer {
33 struct timer_list timer; 35 struct delayed_work dly_wrk;
34 struct brcms_info *wl; 36 struct brcms_info *wl;
35 void (*fn) (void *); 37 void (*fn) (void *); /* function called upon expiration */
36 void *arg; /* argument to fn */ 38 void *arg; /* fixed argument provided to called function */
37 uint ms; 39 uint ms;
38 bool periodic; 40 bool periodic;
39 bool set; 41 bool set; /* indicates if timer is active */
40 struct brcms_timer *next; 42 struct brcms_timer *next; /* for freeing on unload */
41#ifdef BCMDBG 43#ifdef BCMDBG
42 char *name; /* Description of the timer */ 44 char *name; /* Description of the timer */
43#endif 45#endif