mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
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:
commit
d67703fced
80 changed files with 1519 additions and 913 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue