diff --git a/[refs] b/[refs] index d736aac0ab70..62ee30b2df7a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bcff122d478b774f4fd5262f35eedebe2f2fb274 +refs/heads/master: 50c4afb99166dc0d2e8a0b063fe83befaa426a44 diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index bdaab1391d4e..83e8b497e6db 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -350,14 +350,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, } } - -static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, - u8 erp_value) +static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, + bool use_protection, + bool use_short_preamble) { struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; struct ieee80211_if_sta *ifsta = &sdata->u.sta; - bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; - bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; DECLARE_MAC_BUF(mac); u32 changed = 0; @@ -388,6 +386,32 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, return changed; } +static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, + u8 erp_value) +{ + bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; + bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; + + return ieee80211_handle_protect_preamb(sdata, + use_protection, use_short_preamble); +} + +static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta_bss *bss) +{ + u32 changed = 0; + + if (bss->has_erp_value) + changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value); + else { + u16 capab = bss->capability; + changed |= ieee80211_handle_protect_preamb(sdata, false, + (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); + } + + return changed; +} + int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, struct ieee80211_ht_info *ht_info) { @@ -511,9 +535,7 @@ static void ieee80211_set_associated(struct net_device *dev, sdata->bss_conf.beacon_int = bss->beacon_int; sdata->bss_conf.timestamp = bss->timestamp; - if (bss->has_erp_value) - changed |= ieee80211_handle_erp_ie( - sdata, bss->erp_value); + changed |= ieee80211_handle_bss_capability(sdata, bss); ieee80211_rx_bss_put(dev, bss); } @@ -2777,6 +2799,11 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, if (elems.erp_info && elems.erp_info_len >= 1) changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); + else { + u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info); + changed |= ieee80211_handle_protect_preamb(sdata, false, + (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); + } if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { diff --git a/trunk/net/tipc/ref.c b/trunk/net/tipc/ref.c index 89cbab24d08f..c38744c96ed1 100644 --- a/trunk/net/tipc/ref.c +++ b/trunk/net/tipc/ref.c @@ -2,7 +2,7 @@ * net/tipc/ref.c: TIPC object registry code * * Copyright (c) 1991-2006, Ericsson AB - * Copyright (c) 2004-2007, Wind River Systems + * Copyright (c) 2004-2005, Wind River Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,60 +36,32 @@ #include "core.h" #include "ref.h" - -/** - * struct reference - TIPC object reference entry - * @object: pointer to object associated with reference entry - * @lock: spinlock controlling access to object - * @ref: reference value for object (combines instance & array index info) - */ - -struct reference { - void *object; - spinlock_t lock; - u32 ref; -}; - -/** - * struct tipc_ref_table - table of TIPC object reference entries - * @entries: pointer to array of reference entries - * @capacity: array index of first unusable entry - * @init_point: array index of first uninitialized entry - * @first_free: array index of first unused object reference entry - * @last_free: array index of last unused object reference entry - * @index_mask: bitmask for array index portion of reference values - * @start_mask: initial value for instance value portion of reference values - */ - -struct ref_table { - struct reference *entries; - u32 capacity; - u32 init_point; - u32 first_free; - u32 last_free; - u32 index_mask; - u32 start_mask; -}; +#include "port.h" +#include "subscr.h" +#include "name_distr.h" +#include "name_table.h" +#include "config.h" +#include "discover.h" +#include "bearer.h" +#include "node.h" +#include "bcast.h" /* * Object reference table consists of 2**N entries. * - * State Object ptr Reference - * ----- ---------- --------- - * In use non-NULL XXXX|own index - * (XXXX changes each time entry is acquired) - * Free NULL YYYY|next free index - * (YYYY is one more than last used XXXX) - * Uninitialized NULL 0 + * A used entry has object ptr != 0, reference == XXXX|own index + * (XXXX changes each time entry is acquired) + * A free entry has object ptr == 0, reference == YYYY|next free index + * (YYYY is one more than last used XXXX) * - * Entry 0 is not used; this allows index 0 to denote the end of the free list. + * Free list is initially chained from entry (2**N)-1 to entry 1. + * Entry 0 is not used to allow index 0 to indicate the end of the free list. * - * Note that a reference value of 0 does not necessarily indicate that an - * entry is uninitialized, since the last entry in the free list could also - * have a reference value of 0 (although this is unlikely). + * Note: Any accidental reference of the form XXXX|0--0 won't match entry 0 + * because entry 0's reference field has the form XXXX|1--1. */ -static struct ref_table tipc_ref_table = { NULL }; +struct ref_table tipc_ref_table = { NULL }; static DEFINE_RWLOCK(ref_table_lock); @@ -100,29 +72,29 @@ static DEFINE_RWLOCK(ref_table_lock); int tipc_ref_table_init(u32 requested_size, u32 start) { struct reference *table; - u32 actual_size; - - /* account for unused entry, then round up size to a power of 2 */ - - requested_size++; - for (actual_size = 16; actual_size < requested_size; actual_size <<= 1) - /* do nothing */ ; - - /* allocate table & mark all entries as uninitialized */ + u32 sz = 1 << 4; + u32 index_mask; + int i; - table = __vmalloc(actual_size * sizeof(struct reference), - GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); + while (sz < requested_size) { + sz <<= 1; + } + table = vmalloc(sz * sizeof(*table)); if (table == NULL) return -ENOMEM; + write_lock_bh(&ref_table_lock); + index_mask = sz - 1; + for (i = sz - 1; i >= 0; i--) { + table[i].object = NULL; + spin_lock_init(&table[i].lock); + table[i].data.next_plus_upper = (start & ~index_mask) + i - 1; + } tipc_ref_table.entries = table; - tipc_ref_table.capacity = requested_size; - tipc_ref_table.init_point = 1; - tipc_ref_table.first_free = 0; - tipc_ref_table.last_free = 0; - tipc_ref_table.index_mask = actual_size - 1; - tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask; - + tipc_ref_table.index_mask = index_mask; + tipc_ref_table.first_free = sz - 1; + tipc_ref_table.last_free = 1; + write_unlock_bh(&ref_table_lock); return TIPC_OK; } @@ -153,7 +125,7 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) u32 index; u32 index_mask; u32 next_plus_upper; - u32 ref; + u32 reference = 0; if (!object) { err("Attempt to acquire reference to non-existent object\n"); @@ -164,8 +136,6 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) return 0; } - /* take a free entry, if available; otherwise initialize a new entry */ - write_lock_bh(&ref_table_lock); if (tipc_ref_table.first_free) { index = tipc_ref_table.first_free; @@ -173,29 +143,17 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) index_mask = tipc_ref_table.index_mask; /* take lock in case a previous user of entry still holds it */ spin_lock_bh(&entry->lock); - next_plus_upper = entry->ref; + next_plus_upper = entry->data.next_plus_upper; tipc_ref_table.first_free = next_plus_upper & index_mask; - ref = (next_plus_upper & ~index_mask) + index; - entry->ref = ref; + reference = (next_plus_upper & ~index_mask) + index; + entry->data.reference = reference; entry->object = object; + if (lock != NULL) + *lock = &entry->lock; spin_unlock_bh(&entry->lock); - *lock = &entry->lock; - } - else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { - index = tipc_ref_table.init_point++; - entry = &(tipc_ref_table.entries[index]); - spin_lock_init(&entry->lock); - ref = tipc_ref_table.start_mask + index; - entry->ref = ref; - entry->object = object; - *lock = &entry->lock; - } - else { - ref = 0; } write_unlock_bh(&ref_table_lock); - - return ref; + return reference; } /** @@ -211,99 +169,42 @@ void tipc_ref_discard(u32 ref) u32 index; u32 index_mask; + if (!ref) { + err("Attempt to discard reference 0\n"); + return; + } if (!tipc_ref_table.entries) { err("Reference table not found during discard attempt\n"); return; } + write_lock_bh(&ref_table_lock); index_mask = tipc_ref_table.index_mask; index = ref & index_mask; entry = &(tipc_ref_table.entries[index]); - write_lock_bh(&ref_table_lock); - if (!entry->object) { err("Attempt to discard reference to non-existent object\n"); goto exit; } - if (entry->ref != ref) { + if (entry->data.reference != ref) { err("Attempt to discard non-existent reference\n"); goto exit; } - /* - * mark entry as unused; increment instance part of entry's reference - * to invalidate any subsequent references - */ - + /* mark entry as unused */ entry->object = NULL; - entry->ref = (ref & ~index_mask) + (index_mask + 1); - - /* append entry to free entry list */ - if (tipc_ref_table.first_free == 0) tipc_ref_table.first_free = index; else - tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index; + /* next_plus_upper is always XXXX|0--0 for last free entry */ + tipc_ref_table.entries[tipc_ref_table.last_free].data.next_plus_upper + |= index; tipc_ref_table.last_free = index; + /* increment upper bits of entry to invalidate subsequent references */ + entry->data.next_plus_upper = (ref & ~index_mask) + (index_mask + 1); exit: write_unlock_bh(&ref_table_lock); } -/** - * tipc_ref_lock - lock referenced object and return pointer to it - */ - -void *tipc_ref_lock(u32 ref) -{ - if (likely(tipc_ref_table.entries)) { - struct reference *entry; - - entry = &tipc_ref_table.entries[ref & - tipc_ref_table.index_mask]; - if (likely(entry->ref != 0)) { - spin_lock_bh(&entry->lock); - if (likely((entry->ref == ref) && (entry->object))) - return entry->object; - spin_unlock_bh(&entry->lock); - } - } - return NULL; -} - -/** - * tipc_ref_unlock - unlock referenced object - */ - -void tipc_ref_unlock(u32 ref) -{ - if (likely(tipc_ref_table.entries)) { - struct reference *entry; - - entry = &tipc_ref_table.entries[ref & - tipc_ref_table.index_mask]; - if (likely((entry->ref == ref) && (entry->object))) - spin_unlock_bh(&entry->lock); - else - err("Attempt to unlock non-existent reference\n"); - } -} - -/** - * tipc_ref_deref - return pointer referenced object (without locking it) - */ - -void *tipc_ref_deref(u32 ref) -{ - if (likely(tipc_ref_table.entries)) { - struct reference *entry; - - entry = &tipc_ref_table.entries[ref & - tipc_ref_table.index_mask]; - if (likely(entry->ref == ref)) - return entry->object; - } - return NULL; -} - diff --git a/trunk/net/tipc/ref.h b/trunk/net/tipc/ref.h index 7e3798ea93b9..38f3a7f4a78d 100644 --- a/trunk/net/tipc/ref.h +++ b/trunk/net/tipc/ref.h @@ -2,7 +2,7 @@ * net/tipc/ref.h: Include file for TIPC object registry code * * Copyright (c) 1991-2006, Ericsson AB - * Copyright (c) 2005-2006, Wind River Systems + * Copyright (c) 2005, Wind River Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,14 +37,95 @@ #ifndef _TIPC_REF_H #define _TIPC_REF_H +/** + * struct reference - TIPC object reference entry + * @object: pointer to object associated with reference entry + * @lock: spinlock controlling access to object + * @data: reference value associated with object (or link to next unused entry) + */ + +struct reference { + void *object; + spinlock_t lock; + union { + u32 next_plus_upper; + u32 reference; + } data; +}; + +/** + * struct tipc_ref_table - table of TIPC object reference entries + * @entries: pointer to array of reference entries + * @index_mask: bitmask for array index portion of reference values + * @first_free: array index of first unused object reference entry + * @last_free: array index of last unused object reference entry + */ + +struct ref_table { + struct reference *entries; + u32 index_mask; + u32 first_free; + u32 last_free; +}; + +extern struct ref_table tipc_ref_table; + int tipc_ref_table_init(u32 requested_size, u32 start); void tipc_ref_table_stop(void); u32 tipc_ref_acquire(void *object, spinlock_t **lock); void tipc_ref_discard(u32 ref); -void *tipc_ref_lock(u32 ref); -void tipc_ref_unlock(u32 ref); -void *tipc_ref_deref(u32 ref); + +/** + * tipc_ref_lock - lock referenced object and return pointer to it + */ + +static inline void *tipc_ref_lock(u32 ref) +{ + if (likely(tipc_ref_table.entries)) { + struct reference *r = + &tipc_ref_table.entries[ref & tipc_ref_table.index_mask]; + + spin_lock_bh(&r->lock); + if (likely(r->data.reference == ref)) + return r->object; + spin_unlock_bh(&r->lock); + } + return NULL; +} + +/** + * tipc_ref_unlock - unlock referenced object + */ + +static inline void tipc_ref_unlock(u32 ref) +{ + if (likely(tipc_ref_table.entries)) { + struct reference *r = + &tipc_ref_table.entries[ref & tipc_ref_table.index_mask]; + + if (likely(r->data.reference == ref)) + spin_unlock_bh(&r->lock); + else + err("tipc_ref_unlock() invoked using obsolete reference\n"); + } +} + +/** + * tipc_ref_deref - return pointer referenced object (without locking it) + */ + +static inline void *tipc_ref_deref(u32 ref) +{ + if (likely(tipc_ref_table.entries)) { + struct reference *r = + &tipc_ref_table.entries[ref & tipc_ref_table.index_mask]; + + if (likely(r->data.reference == ref)) + return r->object; + } + return NULL; +} #endif