Here's another round of updates for -next:

* big A-MSDU RX performance improvement (avoid linearize of paged RX)
  * rfkill changes: cleanups, documentation, platform properties
  * basic PBSS support in cfg80211
  * MU-MIMO action frame processing support
  * BlockAck reordering & duplicate detection offload support
  * various cleanups & little fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABCgAGBQJW0LZ0AAoJEGt7eEactAAdde0P/2meIOehuHBuAtL7REVoNhri
 bz9eSHMTg+ozCspL7F6vW1ifDI9AaJEaqJccmriueE/UQVC3VXRPGRJ4SFCwZGo9
 Zrtys2v9wOq0+XhxyN65Ucf41O9F/5FFabR5OFbf/pZhW5b2cubEjD1P4BB76Iya
 8O6wf9oDDjt3zJgYK+sygm3k9wtDVrH3qEbj8IDnCy22P7010qCsfok9swfaq8OB
 DBgb6BVfDOFTNXvJGH5fRuUKZdtovzzxorXnoG+zjmKmFdMVdgIYj9+2QfnMjW03
 B4/W85svcLLH8V3lHZc4G8oKM4J4XtjH1PskKIMF7ThJsKGMf8tL2vpt9rr8iscd
 Y9SwTEGc9JmhL7n2FaQFlY6ScLcp4ML+2rXxDOMpBmgF3Ne3yfBsJhLKZEl8vSfI
 mKhzGXpUKjJxJWIxkR0ylJy4/zHeIXkgRlUEhb8t+jgAqvOBTwiVY+vljHCDUERa
 sH40r1OqnGJtOHkSRqXSpxwXW+eKgyDd7fnnRX/tyttp2Fuew27/fN63SjpsfN6O
 3lfSM5bl3FcCKx7vqTLuqzsoqGvDDYkSq6GDfKDqeZIk0vaXA3SJNEOKgymFWQfR
 rzsaXvTbBT34GYRg3xS2NCxlmcBPemei/q0x6ZOffxhF41Qpqjs1dPB1Yq3AW4jD
 HGF+NdRbWEqEFVIjQa8w
 =JHOe
 -----END PGP SIGNATURE-----

Merge tag 'mac80211-next-for-davem-2016-02-26' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
Here's another round of updates for -next:
 * big A-MSDU RX performance improvement (avoid linearize of paged RX)
 * rfkill changes: cleanups, documentation, platform properties
 * basic PBSS support in cfg80211
 * MU-MIMO action frame processing support
 * BlockAck reordering & duplicate detection offload support
 * various cleanups & little fixes
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2016-03-01 17:02:30 -05:00
commit d67703fced
80 changed files with 1519 additions and 913 deletions

View file

@ -57,6 +57,8 @@ struct rfkill {
bool registered;
bool persistent;
bool polling_paused;
bool suspended;
const struct rfkill_ops *ops;
void *data;
@ -233,29 +235,6 @@ static void rfkill_event(struct rfkill *rfkill)
rfkill_send_events(rfkill, RFKILL_OP_CHANGE);
}
static bool __rfkill_set_hw_state(struct rfkill *rfkill,
bool blocked, bool *change)
{
unsigned long flags;
bool prev, any;
BUG_ON(!rfkill);
spin_lock_irqsave(&rfkill->lock, flags);
prev = !!(rfkill->state & RFKILL_BLOCK_HW);
if (blocked)
rfkill->state |= RFKILL_BLOCK_HW;
else
rfkill->state &= ~RFKILL_BLOCK_HW;
*change = prev != blocked;
any = !!(rfkill->state & RFKILL_BLOCK_ANY);
spin_unlock_irqrestore(&rfkill->lock, flags);
rfkill_led_trigger_event(rfkill);
return any;
}
/**
* rfkill_set_block - wrapper for set_block method
*
@ -285,7 +264,7 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
spin_lock_irqsave(&rfkill->lock, flags);
prev = rfkill->state & RFKILL_BLOCK_SW;
if (rfkill->state & RFKILL_BLOCK_SW)
if (prev)
rfkill->state |= RFKILL_BLOCK_SW_PREV;
else
rfkill->state &= ~RFKILL_BLOCK_SW_PREV;
@ -303,8 +282,8 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
spin_lock_irqsave(&rfkill->lock, flags);
if (err) {
/*
* Failed -- reset status to _prev, this may be different
* from what set set _PREV to earlier in this function
* Failed -- reset status to _PREV, which may be different
* from what we have set _PREV to earlier in this function
* if rfkill_set_sw_state was invoked.
*/
if (rfkill->state & RFKILL_BLOCK_SW_PREV)
@ -323,6 +302,19 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
rfkill_event(rfkill);
}
static void rfkill_update_global_state(enum rfkill_type type, bool blocked)
{
int i;
if (type != RFKILL_TYPE_ALL) {
rfkill_global_states[type].cur = blocked;
return;
}
for (i = 0; i < NUM_RFKILL_TYPES; i++)
rfkill_global_states[i].cur = blocked;
}
#ifdef CONFIG_RFKILL_INPUT
static atomic_t rfkill_input_disabled = ATOMIC_INIT(0);
@ -332,8 +324,7 @@ static atomic_t rfkill_input_disabled = ATOMIC_INIT(0);
* @blocked: the new state
*
* This function sets the state of all switches of given type,
* unless a specific switch is claimed by userspace (in which case,
* that switch is left alone) or suspended.
* unless a specific switch is suspended.
*
* Caller must have acquired rfkill_global_mutex.
*/
@ -341,15 +332,7 @@ static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)
{
struct rfkill *rfkill;
if (type == RFKILL_TYPE_ALL) {
int i;
for (i = 0; i < NUM_RFKILL_TYPES; i++)
rfkill_global_states[i].cur = blocked;
} else {
rfkill_global_states[type].cur = blocked;
}
rfkill_update_global_state(type, blocked);
list_for_each_entry(rfkill, &rfkill_list, node) {
if (rfkill->type != type && type != RFKILL_TYPE_ALL)
continue;
@ -477,17 +460,28 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type)
}
#endif
bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
{
bool ret, change;
unsigned long flags;
bool ret, prev;
ret = __rfkill_set_hw_state(rfkill, blocked, &change);
BUG_ON(!rfkill);
spin_lock_irqsave(&rfkill->lock, flags);
prev = !!(rfkill->state & RFKILL_BLOCK_HW);
if (blocked)
rfkill->state |= RFKILL_BLOCK_HW;
else
rfkill->state &= ~RFKILL_BLOCK_HW;
ret = !!(rfkill->state & RFKILL_BLOCK_ANY);
spin_unlock_irqrestore(&rfkill->lock, flags);
rfkill_led_trigger_event(rfkill);
if (!rfkill->registered)
return ret;
if (change)
if (prev != blocked)
schedule_work(&rfkill->uevent_work);
return ret;
@ -582,6 +576,34 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
}
EXPORT_SYMBOL(rfkill_set_states);
static const char * const rfkill_types[] = {
NULL, /* RFKILL_TYPE_ALL */
"wlan",
"bluetooth",
"ultrawideband",
"wimax",
"wwan",
"gps",
"fm",
"nfc",
};
enum rfkill_type rfkill_find_type(const char *name)
{
int i;
BUILD_BUG_ON(ARRAY_SIZE(rfkill_types) != NUM_RFKILL_TYPES);
if (!name)
return RFKILL_TYPE_ALL;
for (i = 1; i < NUM_RFKILL_TYPES; i++)
if (!strcmp(name, rfkill_types[i]))
return i;
return RFKILL_TYPE_ALL;
}
EXPORT_SYMBOL(rfkill_find_type);
static ssize_t name_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@ -591,38 +613,12 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(name);
static const char *rfkill_get_type_str(enum rfkill_type type)
{
BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_NFC + 1);
switch (type) {
case RFKILL_TYPE_WLAN:
return "wlan";
case RFKILL_TYPE_BLUETOOTH:
return "bluetooth";
case RFKILL_TYPE_UWB:
return "ultrawideband";
case RFKILL_TYPE_WIMAX:
return "wimax";
case RFKILL_TYPE_WWAN:
return "wwan";
case RFKILL_TYPE_GPS:
return "gps";
case RFKILL_TYPE_FM:
return "fm";
case RFKILL_TYPE_NFC:
return "nfc";
default:
BUG();
}
}
static ssize_t type_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct rfkill *rfkill = to_rfkill(dev);
return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
return sprintf(buf, "%s\n", rfkill_types[rfkill->type]);
}
static DEVICE_ATTR_RO(type);
@ -730,20 +726,12 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(state);
static ssize_t claim_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n", 0);
}
static DEVICE_ATTR_RO(claim);
static struct attribute *rfkill_dev_attrs[] = {
&dev_attr_name.attr,
&dev_attr_type.attr,
&dev_attr_index.attr,
&dev_attr_persistent.attr,
&dev_attr_state.attr,
&dev_attr_claim.attr,
&dev_attr_soft.attr,
&dev_attr_hard.attr,
NULL,
@ -768,7 +756,7 @@ static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
if (error)
return error;
error = add_uevent_var(env, "RFKILL_TYPE=%s",
rfkill_get_type_str(rfkill->type));
rfkill_types[rfkill->type]);
if (error)
return error;
spin_lock_irqsave(&rfkill->lock, flags);
@ -786,6 +774,7 @@ void rfkill_pause_polling(struct rfkill *rfkill)
if (!rfkill->ops->poll)
return;
rfkill->polling_paused = true;
cancel_delayed_work_sync(&rfkill->poll_work);
}
EXPORT_SYMBOL(rfkill_pause_polling);
@ -797,6 +786,11 @@ void rfkill_resume_polling(struct rfkill *rfkill)
if (!rfkill->ops->poll)
return;
rfkill->polling_paused = false;
if (rfkill->suspended)
return;
queue_delayed_work(system_power_efficient_wq,
&rfkill->poll_work, 0);
}
@ -807,7 +801,8 @@ static int rfkill_suspend(struct device *dev)
{
struct rfkill *rfkill = to_rfkill(dev);
rfkill_pause_polling(rfkill);
rfkill->suspended = true;
cancel_delayed_work_sync(&rfkill->poll_work);
return 0;
}
@ -817,12 +812,16 @@ static int rfkill_resume(struct device *dev)
struct rfkill *rfkill = to_rfkill(dev);
bool cur;
rfkill->suspended = false;
if (!rfkill->persistent) {
cur = !!(rfkill->state & RFKILL_BLOCK_SW);
rfkill_set_block(rfkill, cur);
}
rfkill_resume_polling(rfkill);
if (rfkill->ops->poll && !rfkill->polling_paused)
queue_delayed_work(system_power_efficient_wq,
&rfkill->poll_work, 0);
return 0;
}
@ -1164,15 +1163,8 @@ static ssize_t rfkill_fop_write(struct file *file, const char __user *buf,
mutex_lock(&rfkill_global_mutex);
if (ev.op == RFKILL_OP_CHANGE_ALL) {
if (ev.type == RFKILL_TYPE_ALL) {
enum rfkill_type i;
for (i = 0; i < NUM_RFKILL_TYPES; i++)
rfkill_global_states[i].cur = ev.soft;
} else {
rfkill_global_states[ev.type].cur = ev.soft;
}
}
if (ev.op == RFKILL_OP_CHANGE_ALL)
rfkill_update_global_state(ev.type, ev.soft);
list_for_each_entry(rfkill, &rfkill_list, node) {
if (rfkill->idx != ev.idx && ev.op != RFKILL_OP_CHANGE_ALL)
@ -1261,10 +1253,8 @@ static struct miscdevice rfkill_miscdev = {
static int __init rfkill_init(void)
{
int error;
int i;
for (i = 0; i < NUM_RFKILL_TYPES; i++)
rfkill_global_states[i].cur = !rfkill_default_state;
rfkill_update_global_state(RFKILL_TYPE_ALL, !rfkill_default_state);
error = class_register(&rfkill_class);
if (error)