Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 90801
b: refs/heads/master
c: 3a24576
h: refs/heads/master
i:
  90799: f3662c6
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Apr 16, 2008
1 parent c9f2daa commit bbc7a28
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 51e8b885902fc8cc2ded48322ad9402bbcff23fe
refs/heads/master: 3a245766901a9dfdc3f53457a7954b369b50f281
84 changes: 52 additions & 32 deletions trunk/net/mac80211/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,61 +355,74 @@ void ieee80211_key_link(struct ieee80211_key *key,

add_todo(key, KEY_FLAG_TODO_ADD_DEBUGFS);
if (netif_running(sdata->dev))
add_todo(key, KEY_FLAG_TODO_HWACCEL);
add_todo(key, KEY_FLAG_TODO_HWACCEL_ADD);
}

void ieee80211_key_free(struct ieee80211_key *key)
static void __ieee80211_key_free(struct ieee80211_key *key)
{
unsigned long flags;

if (!key)
return;

/*
* Replace key with nothingness if it was ever used.
*/
if (key->sdata) {
spin_lock_irqsave(&key->sdata->local->sta_lock, flags);
if (key->sdata)
__ieee80211_key_replace(key->sdata, key->sta,
key, NULL);
spin_unlock_irqrestore(&key->sdata->local->sta_lock, flags);
}

add_todo(key, KEY_FLAG_TODO_DELETE);
}

void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
void ieee80211_key_free(struct ieee80211_key *key)
{
struct ieee80211_key *key;

might_sleep();
unsigned long flags;

if (WARN_ON(!netif_running(sdata->dev)))
if (!key)
return;

ieee80211_key_lock();
spin_lock_irqsave(&key->sdata->local->sta_lock, flags);
__ieee80211_key_free(key);
spin_unlock_irqrestore(&key->sdata->local->sta_lock, flags);
}

/*
* To be safe against concurrent manipulations of the list (which shouldn't
* actually happen) we need to hold the spinlock. But under the spinlock we
* can't actually do much, so we defer processing to the todo list. Then run
* the todo list to be sure the operation and possibly previously pending
* operations are completed.
*/
static void ieee80211_todo_for_each_key(struct ieee80211_sub_if_data *sdata,
u32 todo_flags)
{
struct ieee80211_key *key;
unsigned long flags;

might_sleep();

spin_lock_irqsave(&sdata->local->sta_lock, flags);
list_for_each_entry(key, &sdata->key_list, list)
ieee80211_key_enable_hw_accel(key);
add_todo(key, todo_flags);
spin_unlock_irqrestore(&sdata->local->sta_lock, flags);

ieee80211_key_unlock();
ieee80211_key_todo();
}

void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_key *key;
ASSERT_RTNL();

might_sleep();
if (WARN_ON(!netif_running(sdata->dev)))
return;

ieee80211_key_lock();
ieee80211_todo_for_each_key(sdata, KEY_FLAG_TODO_HWACCEL_ADD);
}

list_for_each_entry(key, &sdata->key_list, list)
ieee80211_key_disable_hw_accel(key);
void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
{
ASSERT_RTNL();

ieee80211_key_unlock();
ieee80211_todo_for_each_key(sdata, KEY_FLAG_TODO_HWACCEL_REMOVE);
}

static void __ieee80211_key_free(struct ieee80211_key *key)
static void __ieee80211_key_destroy(struct ieee80211_key *key)
{
if (!key)
return;
Expand Down Expand Up @@ -440,7 +453,8 @@ static void __ieee80211_key_todo(void)
list_del_init(&key->todo);
todoflags = key->flags & (KEY_FLAG_TODO_ADD_DEBUGFS |
KEY_FLAG_TODO_DEFKEY |
KEY_FLAG_TODO_HWACCEL |
KEY_FLAG_TODO_HWACCEL_ADD |
KEY_FLAG_TODO_HWACCEL_REMOVE |
KEY_FLAG_TODO_DELETE);
key->flags &= ~todoflags;
spin_unlock(&todo_lock);
Expand All @@ -456,12 +470,16 @@ static void __ieee80211_key_todo(void)
ieee80211_debugfs_key_add_default(key->sdata);
work_done = true;
}
if (todoflags & KEY_FLAG_TODO_HWACCEL) {
if (todoflags & KEY_FLAG_TODO_HWACCEL_ADD) {
ieee80211_key_enable_hw_accel(key);
work_done = true;
}
if (todoflags & KEY_FLAG_TODO_HWACCEL_REMOVE) {
ieee80211_key_disable_hw_accel(key);
work_done = true;
}
if (todoflags & KEY_FLAG_TODO_DELETE) {
__ieee80211_key_free(key);
__ieee80211_key_destroy(key);
work_done = true;
}

Expand All @@ -482,14 +500,16 @@ void ieee80211_key_todo(void)
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_key *key, *tmp;
LIST_HEAD(tmp_list);
unsigned long flags;

ieee80211_key_lock();

ieee80211_debugfs_key_remove_default(sdata);

spin_lock_irqsave(&sdata->local->sta_lock, flags);
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
ieee80211_key_free(key);
__ieee80211_key_free(key);
spin_unlock_irqrestore(&sdata->local->sta_lock, flags);

__ieee80211_key_todo();

Expand Down
11 changes: 7 additions & 4 deletions trunk/net/mac80211/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,19 @@ struct sta_info;
* @KEY_FLAG_TODO_DELETE: Key is marked for deletion and will, after an
* RCU grace period, no longer be reachable other than from the
* todo list.
* @KEY_FLAG_TODO_HWACCEL: Key needs to be added to hardware acceleration.
* @KEY_FLAG_TODO_HWACCEL_ADD: Key needs to be added to hardware acceleration.
* @KEY_FLAG_TODO_HWACCEL_REMOVE: Key needs to be removed from hardware
* acceleration.
* @KEY_FLAG_TODO_DEFKEY: Key is default key and debugfs needs to be updated.
* @KEY_FLAG_TODO_ADD_DEBUGFS: Key needs to be added to debugfs.
*/
enum ieee80211_internal_key_flags {
KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0),
KEY_FLAG_TODO_DELETE = BIT(1),
KEY_FLAG_TODO_HWACCEL = BIT(2),
KEY_FLAG_TODO_DEFKEY = BIT(3),
KEY_FLAG_TODO_ADD_DEBUGFS = BIT(4),
KEY_FLAG_TODO_HWACCEL_ADD = BIT(2),
KEY_FLAG_TODO_HWACCEL_REMOVE = BIT(3),
KEY_FLAG_TODO_DEFKEY = BIT(4),
KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5),
};

struct ieee80211_key {
Expand Down

0 comments on commit bbc7a28

Please sign in to comment.