* [PATCH 0/2] net_sched: Remove broken tc actions
From: Eric W. Biederman @ 2013-10-27 13:40 UTC (permalink / raw)
To: David Miller; +Cc: netdev, alexander.h.duyck, jhs
While auditing the code to make certain it would be safe to enable the
user namespace root to use tc actions I stumbled on the strange fact
that two of the tc modules in the kernel have been broken for more
years than I care to think about.
In particular neither of these two modules implements the tc_action_ops
lookup method. Which means that in practice neither RTM_GETACTION nor
RTM_DELACTION work. And with RTM_DELACTION broken that looks like a
permanent leak of kernel memory to me.
A leak I am not happy at root having and certainly not something I want
to allow unprivileged users access to.
On the premise that 5+ years is too long to wait for someone to notice,
complain and get this code fixed let's just remove these broken tc
modules.
Eric W. Biederman (2):
net_sched: Remove broken act_skbedit
net_sched: Remove broken act_simple
include/net/tc_act/tc_defact.h | 14 --
include/net/tc_act/tc_skbedit.h | 36 -----
include/uapi/linux/tc_act/Kbuild | 2 -
include/uapi/linux/tc_act/tc_defact.h | 19 ---
include/uapi/linux/tc_act/tc_skbedit.h | 46 -------
net/sched/Kconfig | 25 ----
net/sched/Makefile | 2 -
net/sched/act_simple.c | 225 --------------------------------
net/sched/act_skbedit.c | 224 -------------------------------
9 files changed, 0 insertions(+), 593 deletions(-)
^ permalink raw reply
* Re: [patch net-next] ipv6: allow userspace to create address with IFLA_F_TEMPORARY flag
From: Jiri Pirko @ 2013-10-27 13:29 UTC (permalink / raw)
To: Vladislav Yasevich
Cc: netdev@vger.kernel.org, David Miller, kuznet, jmorris, yoshfuji,
kaber, thaller, Stephen Hemminger
In-Reply-To: <CAGCdqXHUW=RJf67qPXVRhPY__GAs02+G9mJV7agN5pDdfELXXA@mail.gmail.com>
Sat, Oct 26, 2013 at 01:05:34AM CEST, vyasevich@gmail.com wrote:
>On Thu, Oct 24, 2013 at 9:45 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> This is needed in order to implement userspace address configuration,
>> namely ip6-privacy (rfc4941) in NetworkManager.
>>
>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>> ---
>> net/ipv6/addrconf.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>> index cd3fb30..962c7c9 100644
>> --- a/net/ipv6/addrconf.c
>> +++ b/net/ipv6/addrconf.c
>> @@ -3715,7 +3715,8 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
>> return -ENODEV;
>>
>> /* We ignore other flags so far. */
>> - ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
>> + ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS |
>> + IFA_F_TEMPORARY);
>>
>> ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
>> if (ifa == NULL) {
>> --
>> 1.8.3.1
>>
>
>Jiri
>
>So, is the idea behind this is that all of temp address management
>would be done in user space? If so, then you
>may have to verify that no-one sets the lifetime values on the prefix
>in your other patch. I am still trying to figure out
>why this would be needed.
The idea is to provide possibility to do address configuration not in
kernel but rather in userspace (as it is done for example in NetworkManager)
Maybe I'm missing something, but why is it problem to have the
possibility to set lifetime even for temporary prefix?
>
>Thanks
>-vlad
^ permalink raw reply
* [PATCH net] xen-netback: use jiffies_64 value to calculate credit timeout
From: Wei Liu @ 2013-10-27 11:11 UTC (permalink / raw)
To: xen-devel, netdev
Cc: david.vrabel, jbeulich, annie.li, Wei Liu, Ian Campbell,
Jason Luan
time_after_eq() only works if the delta is < MAX_ULONG/2.
For a 32bit Dom0, if netfront sends packets at a very low rate, the time
between subsequent calls to tx_credit_exceeded() may exceed MAX_ULONG/2
and the test for timer_after_eq() will be incorrect. Credit will not be
replenished and the guest may become unable to send packets (e.g., if
prior to the long gap, all credit was exhausted).
Use jiffies_64 variant to mitigate this problem for 32bit Dom0.
Suggested-by: Jan Beulich <jbeulich@suse.com>
Suggested-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Jason Luan <jianhai.luan@oracle.com>
---
drivers/net/xen-netback/common.h | 1 +
drivers/net/xen-netback/interface.c | 4 ++--
drivers/net/xen-netback/netback.c | 13 ++++++-------
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 5715318..400fea1 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -163,6 +163,7 @@ struct xenvif {
unsigned long credit_usec;
unsigned long remaining_credit;
struct timer_list credit_timeout;
+ u64 credit_window_start;
/* Statistics */
unsigned long rx_gso_checksum_fixup;
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 01bb854..8c45b63 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -312,8 +312,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
vif->credit_bytes = vif->remaining_credit = ~0UL;
vif->credit_usec = 0UL;
init_timer(&vif->credit_timeout);
- /* Initialize 'expires' now: it's used to track the credit window. */
- vif->credit_timeout.expires = jiffies;
+ /* credit window is tracked in credit_window_start */
+ vif->credit_window_start = get_jiffies_64();
dev->netdev_ops = &xenvif_netdev_ops;
dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index f3e591c..1bc0688 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1185,18 +1185,17 @@ out:
static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
{
- unsigned long now = jiffies;
- unsigned long next_credit =
- vif->credit_timeout.expires +
- msecs_to_jiffies(vif->credit_usec / 1000);
+ u64 now = get_jiffies_64();
+ u64 next_credit = vif->credit_window_start +
+ (u64)msecs_to_jiffies(vif->credit_usec / 1000);
/* Timer could already be pending in rare cases. */
if (timer_pending(&vif->credit_timeout))
return true;
/* Passed the point where we can replenish credit? */
- if (time_after_eq(now, next_credit)) {
- vif->credit_timeout.expires = now;
+ if (time_after_eq64(now, next_credit)) {
+ vif->credit_timeout.expires = (unsigned long)now;
tx_add_credit(vif);
}
@@ -1207,7 +1206,7 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
vif->credit_timeout.function =
tx_credit_callback;
mod_timer(&vif->credit_timeout,
- next_credit);
+ (unsigned long)next_credit);
return true;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH net 2/2] bnx2x: Disable VF access on PF removal
From: Yuval Mintz @ 2013-10-27 11:07 UTC (permalink / raw)
To: davem, netdev; +Cc: dmitry, ariele, eilong, Yuval Mintz
In-Reply-To: <1382872021-1116-1-git-send-email-yuvalmin@broadcom.com>
From: Ariel Elior <ariele@broadcom.com>
When the bnx2x driver is rmmoded, if VFs of a given PF will be assigned
to a VM then that PF will be unable to call `pci_disable_sriov()'.
If for that same PF there would also exist unassigned VFs in the hypervisor,
the result will be that after the removal there will still be virtual PCI
functions on the hypervisor.
If the bnx2x module were to be re-inserted, the result will be that the VFs
on the hypervisor will be re-probed directly following the PF's probe, even
though that in regular loading flow sriov is only enabled once PF is loaded.
The probed VF will then try to access its bar, causing a PCI error as the HW
is not in a state enabling such a request.
This patch adds a missing disablement procedure to the PF's removal, one that
sets registers viewable to the VF to indicate that the VFs have no permission
to access the bar, thus resulting in probe errors instead of PCI errors.
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index bf08ad6..5e07efb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -2018,6 +2018,8 @@ failed:
void bnx2x_iov_remove_one(struct bnx2x *bp)
{
+ int vf_idx;
+
/* if SRIOV is not enabled there's nothing to do */
if (!IS_SRIOV(bp))
return;
@@ -2026,6 +2028,18 @@ void bnx2x_iov_remove_one(struct bnx2x *bp)
pci_disable_sriov(bp->pdev);
DP(BNX2X_MSG_IOV, "sriov disabled\n");
+ /* disable access to all VFs */
+ for (vf_idx = 0; vf_idx < bp->vfdb->sriov.total; vf_idx++) {
+ bnx2x_pretend_func(bp,
+ HW_VF_HANDLE(bp,
+ bp->vfdb->sriov.first_vf_in_pf +
+ vf_idx));
+ DP(BNX2X_MSG_IOV, "disabling internal access for vf %d\n",
+ bp->vfdb->sriov.first_vf_in_pf + vf_idx);
+ bnx2x_vf_enable_internal(bp, 0);
+ bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
+ }
+
/* free vf database */
__bnx2x_iov_free_vfdb(bp);
}
@@ -3197,7 +3211,7 @@ int bnx2x_enable_sriov(struct bnx2x *bp)
* the "acquire" messages to appear on the VF PF channel.
*/
DP(BNX2X_MSG_IOV, "about to call enable sriov\n");
- pci_disable_sriov(bp->pdev);
+ bnx2x_disable_sriov(bp);
rc = pci_enable_sriov(bp->pdev, req_vfs);
if (rc) {
BNX2X_ERR("pci_enable_sriov failed with %d\n", rc);
--
1.8.1.227.g44fe835
^ permalink raw reply related
* [PATCH net 0/2] bnx2x: Bug fixes patch series
From: Yuval Mintz @ 2013-10-27 11:06 UTC (permalink / raw)
To: davem, netdev; +Cc: dmitry, ariele, eilong
Hi Dave,
This series contains 2 unrelated fixes:
1. FW asserts during unload might be encountered if specific memory
allocations fail during load.
2. SR-IOV related, fixes a crash that will occour if the driver were to
be rmmoded and then re-probed while there are both assigned and unassigned
VFs originating from the same PF.
Please consider applying these patches to `net'.
Thanks,
Yuval Mintz
^ permalink raw reply
* [PATCH net 1/2] bnx2x: prevent FW assert on low mem during unload
From: Yuval Mintz @ 2013-10-27 11:07 UTC (permalink / raw)
To: davem, netdev; +Cc: dmitry, ariele, eilong, Yuval Mintz
In-Reply-To: <1382872021-1116-1-git-send-email-yuvalmin@broadcom.com>
From: Dmitry Kravkov <dmitry@broadcom.com>
Buffers for FW statistics were allocated at an inappropriate time; In a machine
where the driver encounters problems allocating all of its queues, the driver
would still create FW requests for the statistics of the non-existing queues.
The wrong order of memory allocation could lead to zeroed statistics messages
being sent, leading to fw assert in case function 0 was down.
This changes the order of allocations, guaranteeing that statistic requests will
only be generated for actual queues.
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 4ab4c89..74d6486 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -2545,10 +2545,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
}
}
- /* Allocated memory for FW statistics */
- if (bnx2x_alloc_fw_stats_mem(bp))
- LOAD_ERROR_EXIT(bp, load_error0);
-
/* need to be done after alloc mem, since it's self adjusting to amount
* of memory available for RSS queues
*/
@@ -2558,6 +2554,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
LOAD_ERROR_EXIT(bp, load_error0);
}
+ /* Allocated memory for FW statistics */
+ if (bnx2x_alloc_fw_stats_mem(bp))
+ LOAD_ERROR_EXIT(bp, load_error0);
+
/* request pf to initialize status blocks */
if (IS_VF(bp)) {
rc = bnx2x_vfpf_init(bp);
@@ -2812,8 +2812,8 @@ load_error1:
if (IS_PF(bp))
bnx2x_clear_pf_load(bp);
load_error0:
- bnx2x_free_fp_mem(bp);
bnx2x_free_fw_stats_mem(bp);
+ bnx2x_free_fp_mem(bp);
bnx2x_free_mem(bp);
return rc;
--
1.8.1.227.g44fe835
^ permalink raw reply related
* [PATCH net 0/2] bnx2x: Bug fixes patch series
From: Yuval Mintz @ 2013-10-27 11:06 UTC (permalink / raw)
To: davem, netdev; +Cc: dmitry, ariele, eilong
Hi Dave,
This series contains 2 unrelated fixes:
1. FW asserts during unload might be encountered if specific memory
allocations fail during load.
2. SR-IOV related, fixes a crash that will occour if the driver were to
be rmmoded and then re-probed while there are both assigned and unassigned
VFs originating from the same PF.
Please consider applying these patches to `net'.
Thanks,
Yuval Mintz
^ permalink raw reply
* deadlock when unplugging rtl8192cu controller
From: Ilia Mirkin @ 2013-10-27 7:08 UTC (permalink / raw)
To: netdev
Hello,
I pulled the network controller out, after trying to down the
controller (which failed at the script level, I didn't investigate the
details). Here is the output from echo w > /proc/sysrq-trigger. It
seems like khubd is stuck in schedule while holding rtnl_lock, which
in turn hangs everything else. Apologies for the linewrapping below.
Any other information I should collect should this happen again?
Anything I can do short of rebooting to get things going again?
Bus 002 Device 005: ID 0bda:8176 Realtek Semiconductor Corp.
RTL8188CUS 802.11n WLAN Adapter
[103822.129461] usb 2-2: USB disconnect, device number 5
[103895.563068] SysRq : Show Blocked State
[103895.563072] task PC stack pid father
[103895.563082] khubd D ffff8801c8bf4138 3648 550 2 0x00000000
[103895.563086] ffff8801c818faf8 0000000000000046 ffff8801c818fa98
ffff8801c8925490
[103895.563089] ffff8801c818fb18 ffff8801c8bf3d80 ffff8801c818ffd8
ffff8801c818ffd8
[103895.563091] 0000000000013000 ffff8801c8bf3d80 ffff8801c8bf3d80
ffffffff81c872a0
[103895.563094] Call Trace:
[103895.563100] [<ffffffff816d1599>] schedule+0x64/0x66
[103895.563103] [<ffffffff816d1752>] schedule_preempt_disabled+0xe/0x10
[103895.563106] [<ffffffff816d0688>] __mutex_lock_slowpath+0x13d/0x193
[103895.563110] [<ffffffff81080303>] ? call_usermodehelper_setup+0x59/0x9c
[103895.563116] [<ffffffff816cfbc4>] mutex_lock+0x23/0x37
[103895.563120] [<ffffffff8153df7f>] rtnl_lock+0x15/0x17
[103895.563123] [<ffffffff81689c32>] ieee80211_unregister_hw+0x55/0x10a
[103895.563128] [<ffffffffa03c0b39>] rtl_usb_disconnect+0x47/0xcb [rtl_usb]
[103895.563132] [<ffffffff81418677>] usb_unbind_interface+0x69/0x144
[103895.563135] [<ffffffff813a2fa5>] __device_release_driver+0x89/0xdf
[103895.563137] [<ffffffff813a301e>] device_release_driver+0x23/0x30
[103895.563140] [<ffffffff813a2b2c>] bus_remove_device+0xe9/0xfe
[103895.563142] [<ffffffff813a03a1>] device_del+0x130/0x18a
[103895.563145] [<ffffffff81416817>] usb_disable_device+0x77/0x197
[103895.563149] [<ffffffff8140f93f>] usb_disconnect+0x91/0x15e
[103895.563151] [<ffffffff814110de>] hub_thread+0x652/0xf15
[103895.563154] [<ffffffff8108928f>] ? add_wait_queue+0x49/0x49
[103895.563156] [<ffffffff81410a8c>] ? hub_port_debounce+0xbf/0xbf
[103895.563159] [<ffffffff81410a8c>] ? hub_port_debounce+0xbf/0xbf
[103895.563162] [<ffffffff810889df>] kthread+0x8d/0x95
[103895.563164] [<ffffffff81088952>] ? kthread_freezable_should_stop+0x43/0x43
[103895.563168] [<ffffffff816d901c>] ret_from_fork+0x7c/0xb0
[103895.563170] [<ffffffff81088952>] ? kthread_freezable_should_stop+0x43/0x43
[103895.563194] ntpd D ffff8801c82c5ff8 4864 3211 1 0x00000004
[103895.563197] ffff8801b8d8fcb8 0000000000000082 ffff8801b8d8fc78
ffff8801c8924ce0
[103895.563200] 000000000000d0a0 ffff8801c82c5c40 ffff8801b8d8ffd8
ffff8801b8d8ffd8
[103895.563202] 0000000000013000 ffff8801c82c5c40 ffff8801c085f400
ffffffff81c872a0
[103895.563205] Call Trace:
[103895.563207] [<ffffffff816d1599>] schedule+0x64/0x66
[103895.563210] [<ffffffff816d1752>] schedule_preempt_disabled+0xe/0x10
[103895.563212] [<ffffffff816d0688>] __mutex_lock_slowpath+0x13d/0x193
[103895.563214] [<ffffffff816cfbc4>] mutex_lock+0x23/0x37
[103895.563217] [<ffffffff81079e06>] ? dequeue_signal+0x113/0x122
[103895.563219] [<ffffffff8153df7f>] rtnl_lock+0x15/0x17
[103895.563222] [<ffffffff81541960>] dev_ioctl+0x30/0x620
[103895.563225] [<ffffffff8108fb4a>] ? should_resched+0x9/0x28
[103895.563227] [<ffffffff816d12dc>] ? _cond_resched+0xe/0x22
[103895.563230] [<ffffffff8113a275>] ? kmem_cache_alloc+0x31/0xfe
[103895.563234] [<ffffffff8151dda4>] sock_do_ioctl+0x3b/0x46
[103895.563236] [<ffffffff8151e1f2>] sock_ioctl+0x201/0x20e
[103895.563240] [<ffffffff8114fc1f>] do_vfs_ioctl+0x407/0x448
[103895.563243] [<ffffffff8114339f>] ? alloc_file+0x1e/0xc4
[103895.563245] [<ffffffff816d2193>] ? _raw_spin_lock+0xe/0x10
[103895.563248] [<ffffffff8114fcac>] SyS_ioctl+0x4c/0x70
[103895.563250] [<ffffffff816d90c6>] system_call_fastpath+0x1a/0x1f
[103895.563275] ip D ffff880070d8e7a8 5968 14224 14183 0x00000004
[103895.563278] ffff880077ad9b28 0000000000000086 0000000000000000
ffff8801c826eba0
[103895.563280] 0000000000000000 ffff880070d8e3f0 ffff880077ad9fd8
ffff880077ad9fd8
[103895.563283] 0000000000013000 ffff880070d8e3f0 ffffffff8108ac3a
ffffffff81c872a0
[103895.563285] Call Trace:
[103895.563288] [<ffffffff8108ac3a>] ? need_resched+0x11/0x1d
[103895.563291] [<ffffffff816d1599>] schedule+0x64/0x66
[103895.563293] [<ffffffff816d1752>] schedule_preempt_disabled+0xe/0x10
[103895.563295] [<ffffffff816d0688>] __mutex_lock_slowpath+0x13d/0x193
[103895.563298] [<ffffffff816cfbc4>] mutex_lock+0x23/0x37
[103895.563301] [<ffffffff81527679>] ? __kmalloc_reserve.isra.47+0x2d/0x6d
[103895.563303] [<ffffffff8153df7f>] rtnl_lock+0x15/0x17
[103895.563306] [<ffffffff8153df97>] rtnetlink_rcv+0x16/0x2d
[103895.563309] [<ffffffff8156d56c>] netlink_unicast+0xeb/0x16d
[103895.563312] [<ffffffff8156d8c7>] netlink_sendmsg+0x2d9/0x31a
[103895.563314] [<ffffffff8151fc08>] sock_sendmsg+0x69/0x8a
[103895.563318] [<ffffffff81157665>] ? fget_light+0x38/0x88
[103895.563320] [<ffffffff8152032b>] SYSC_sendto+0xeb/0x110
[103895.563323] [<ffffffff8151f227>] ? move_addr_to_user+0x73/0x96
[103895.563325] [<ffffffff8151f560>] ? SYSC_getsockname+0x74/0x86
[103895.563328] [<ffffffff81520780>] SyS_sendto+0xe/0x10
[103895.563330] [<ffffffff816d90c6>] system_call_fastpath+0x1a/0x1f
[103895.563332] ifconfig D ffff8801b60d5848 5968 14237 3184 0x00000004
[103895.563335] ffff88007b5d1cb8 0000000000000086 0000000000000202
ffff8801bec307b0
[103895.563338] 0000000000000010 ffff8801b60d5490 ffff88007b5d1fd8
ffff88007b5d1fd8
[103895.563340] 0000000000013000 ffff8801b60d5490 ffffffff81c872a0
ffffffff81c872a0
[103895.563342] Call Trace:
[103895.563345] [<ffffffff816d1599>] schedule+0x64/0x66
[103895.563347] [<ffffffff816d1752>] schedule_preempt_disabled+0xe/0x10
[103895.563349] [<ffffffff816d0688>] __mutex_lock_slowpath+0x13d/0x193
[103895.563352] [<ffffffff816cfbc4>] mutex_lock+0x23/0x37
[103895.563354] [<ffffffff8153df7f>] rtnl_lock+0x15/0x17
[103895.563356] [<ffffffff81541960>] dev_ioctl+0x30/0x620
[103895.563360] [<ffffffff811232cf>] ? handle_mm_fault+0x1bd/0x1d7
[103895.563362] [<ffffffff8151dda4>] sock_do_ioctl+0x3b/0x46
[103895.563364] [<ffffffff8151e1f2>] sock_ioctl+0x201/0x20e
[103895.563367] [<ffffffff8114fc1f>] do_vfs_ioctl+0x407/0x448
[103895.563369] [<ffffffff8114fcac>] SyS_ioctl+0x4c/0x70
[103895.563372] [<ffffffff816d90c6>] system_call_fastpath+0x1a/0x1f
^ permalink raw reply
* Re: [gpio:for-next 67/67] pch_gbe_main.c:undefined reference to `devm_gpio_request_one'
From: David Cohen @ 2013-10-27 5:31 UTC (permalink / raw)
To: Darren Hart
Cc: Linus Walleij, David S. Miller, netdev@vger.kernel.org,
Fengguang Wu, Alexandre Courbot, linux-gpio@vger.kernel.org
In-Reply-To: <1382822142.23829.46.camel@dvhart-mobl4.amr.corp.intel.com>
[-- Attachment #1: Type: text/plain, Size: 2853 bytes --]
On 10/26/2013 02:15 PM, Darren Hart wrote:
> On Sat, 2013-10-26 at 21:33 +0100, Darren Hart wrote:
>> On Fri, 2013-10-25 at 14:25 -0700, David Cohen wrote:
>>> On 10/25/2013 02:21 PM, David Cohen wrote:
>>>> Hi Linus,
>>>>
>>>> On 10/25/2013 03:49 AM, Linus Walleij wrote:
>>>>> On Fri, Oct 25, 2013 at 12:41 PM, Linus Walleij
>>>>> <linus.walleij@linaro.org> wrote:
>>>>>
>>>>>>> I wouldn't object to adding a dependency to GPIO_PCH and GPIOLIB
>>>>>>> unconditionally for PCH_GBE as GPIO_PCH is the same chip... but I don't
>>>>>>> know if David Miller would be amenable to that.
>>>>>>
>>>>>> Well we should probably just stick a dependency to GPIOLIB in there.
>>>>>>
>>>>>> - It #includes <linux/gpio.h>
>>>>>> - It uses gpiolib functions to do something vital
>>>>>>
>>>>>> It was just happy that dummy versions were slotted in until now.
>>>>>
>>>>> ...or maybe I'm just confused now?
>>>>>
>>>>> Should we just add a static inline stub of devm_gpio_request_one()?
>>>>
>>>> I am not familiar with the HW. But checking the code, platform
>>>> initialization should fail with a dummy devm_gpio_request_one()
>>>> implementation. IMO it makes more sense to depend on GPIOLIB.
>>>
>>> Actually, forget about it. Despite driver_data->platform_init() may
>>> return error, probe() never checks for it. I think the driver must be
>>> fixed, but in meanwhile a static inline stub seems reasonable.
>>>
>>
>> Ah, that's a problem, and one I created :/ I'm traveling a bit through
>> Europe atm for the conferences. I will try and have a look on the planes
>> and add a check.
>
> Ah, now I remember. The situation is this. If there is a cable plugged
> into the jack, the PHY will not go to sleep. If there isn't, there is a
> good chance it will go to sleep before the driver initializes. If it is
> asleep, the scan for the PHY will fail. If it isn't, the scan will work
> correctly and the device will be properly setup. The code currently
> displays a dev error:
>
> ret = devm_gpio_request_one(&pdev->dev, gpio, flags,
> "minnow_phy_reset");
> if (ret) {
> dev_err(&pdev->dev,
> "ERR: Can't request PHY reset GPIO line '%d'\n", gpio);
>
> But deliberately does not about the probe because there is a chance
> things will work just fine. If they do not, the PHY detection code will
> print display errors about a failure to communicate over RGMII, and the
> device probe will fail from there.
>
> This still seems like the correct approach to me. Does anyone disagree?
Considering this scenario it seems to be correct. But if
devm_gpio_request_one() may fail for "unfriendly" reasons too, then
it's incomplete.
>
> (we still need to sort out the GPIOLIB and GPIO_SCH dependency though of
> course)
Maybe if GPIOLIB has the static inline stubs returning -ENODEV we could
use a patch similar to the one attached here.
Br, David
[-- Attachment #2: pch_gbe_main.patch --]
[-- Type: text/x-patch, Size: 1276 bytes --]
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 5a0f04c..4702876 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2637,8 +2637,11 @@ static int pch_gbe_probe(struct pci_dev *pdev,
adapter->hw.back = adapter;
adapter->hw.reg = pcim_iomap_table(pdev)[PCH_GBE_PCI_BAR];
adapter->pdata = (struct pch_gbe_privdata *)pci_id->driver_data;
- if (adapter->pdata && adapter->pdata->platform_init)
- adapter->pdata->platform_init(pdev);
+ if (adapter->pdata && adapter->pdata->platform_init) {
+ ret = adapter->pdata->platform_init(pdev);
+ if (ret)
+ goto err_free_netdev;
+ }
adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number,
PCI_DEVFN(12, 4));
@@ -2740,9 +2743,9 @@ static int pch_gbe_minnow_platform_init(struct pci_dev *pdev)
ret = devm_gpio_request_one(&pdev->dev, gpio, flags,
"minnow_phy_reset");
if (ret) {
- dev_err(&pdev->dev,
- "ERR: Can't request PHY reset GPIO line '%d'\n", gpio);
- return ret;
+ dev_warn(&pdev->dev,
+ "ERR: Can't request PHY reset GPIO line '%d'\n", gpio);
+ return ret == -ENODEV ? ret : 0;
}
gpio_set_value(gpio, 0);
^ permalink raw reply related
* Re: 16% regression on 10G caused by TCP small queues
From: David Miller @ 2013-10-27 5:07 UTC (permalink / raw)
To: dave.taht; +Cc: stephen, ncardwell, eric.dumazet, netdev
In-Reply-To: <20131027043351.GA27876@lists.bufferbloat.net>
From: Dave Taht <dave.taht@bufferbloat.net>
Date: Sat, 26 Oct 2013 21:33:52 -0700
> On Thu, Oct 24, 2013 at 03:01:21AM -0400, David Miller wrote:
>> From: Stephen Hemminger <stephen@networkplumber.org>
>> Date: Wed, 23 Oct 2013 21:45:57 -0700
>>
>> > Sorry, thought sk_pacing_rate depended on FQ qdisc but it is other way around.
>> > In which case doing merge of these two was sufficient to fix the problem.
>> > With a minor manual fix up to tcp.h.
>>
>> I know, I already have a half-built tree of -stable submissions
>> that does exactlty this.
>
> I know that the "fq" qdisc is not exactly a -stable thing, but if it's simpler
> to include it rather than sort through the patch sets, I'm all for it.
I'm not including 'fq' and it's absolutely not necessary to fix this
bug.
'fq' is only incidentary to this bug fix because it just so happens to
make use of sk->sk_pacing_rate. There is no other connection between
these two things.
^ permalink raw reply
* Re: 16% regression on 10G caused by TCP small queues
From: Dave Taht @ 2013-10-27 4:33 UTC (permalink / raw)
To: David Miller; +Cc: stephen, ncardwell, eric.dumazet, netdev
In-Reply-To: <20131024.030121.477884925478012615.davem@davemloft.net>
On Thu, Oct 24, 2013 at 03:01:21AM -0400, David Miller wrote:
> From: Stephen Hemminger <stephen@networkplumber.org>
> Date: Wed, 23 Oct 2013 21:45:57 -0700
>
> > Sorry, thought sk_pacing_rate depended on FQ qdisc but it is other way around.
> > In which case doing merge of these two was sufficient to fix the problem.
> > With a minor manual fix up to tcp.h.
>
> I know, I already have a half-built tree of -stable submissions
> that does exactlty this.
I know that the "fq" qdisc is not exactly a -stable thing, but if it's simpler
to include it rather than sort through the patch sets, I'm all for it.
^ permalink raw reply
* Netem Delay Normal Distribution
From: anirup dutta @ 2013-10-27 2:31 UTC (permalink / raw)
To: netdev
Hello,
I try this on my device
sudo tc qdisc del dev eth0 root netem delay 100ms 20ms distribution normal
I use iperf for transmitting UDP packets and I modified its code to
get per packet delay. When I plot the distribution of delays and
analyze the delays they pass the normality tests.
The only problem that I am not able to understand is that the mean of
those delays shift to 125ms. Its not only me. There was another study
and it observed the same thing.
http://www.researchgate.net/publication/224256550_An_Empirical_Study_of_NetEm_Network_Emulation_Functionalities/file/d912f5058c9b1e409b.pdf
Figure 7
I found out that this command is valid
sudo tc qdisc del dev eth0 root netem delay 1ms 20ms distribution normal
So I have a feeling that mean gets shifted from the base delay to
avoid negative delay values.
It would be great if someone can confirm how it is implemented?
Regards,
Anirup
^ permalink raw reply
* Re: [PATCH 1/3] vxlan: silence one build warning
From: Zhi Yong Wu @ 2013-10-27 2:30 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, linux-kernel mlist, Zhi Yong Wu
In-Reply-To: <20131026074819.6a5f4e24@samsung-9>
HI, Stephen
I saw it on Fedora 17 without latest kernel. Then what do you think
that it is appropriate to solve this problem? discard this patch? If
yes, i can also agree.
On Sat, Oct 26, 2013 at 10:48 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Sat, 26 Oct 2013 15:06:04 +0800
> Zhi Yong Wu <zwu.kernel@gmail.com> wrote:
>
>> On Fri, Oct 25, 2013 at 11:41 PM, Stephen Hemminger
>> <stephen@networkplumber.org> wrote:
>> > On Fri, 25 Oct 2013 15:49:18 +0800
>> > Zhi Yong Wu <zwu.kernel@gmail.com> wrote:
>> >
>> >> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>> >>
>> >> drivers/net/vxlan.c: In function ‘vxlan_sock_add’:
>> >> drivers/net/vxlan.c:2298:11: warning: ‘sock’ may be used uninitialized in this function [-Wmaybe-uninitialized]
>> >> drivers/net/vxlan.c:2275:17: note: ‘sock’ was declared here
>> >> LD drivers/net/built-in.o
>> >>
>> >> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>> >> ---
>> >> drivers/net/vxlan.c | 2 +-
>> >> 1 file changed, 1 insertion(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
>> >> index 2ef5b62..e15f1af 100644
>> >> --- a/drivers/net/vxlan.c
>> >> +++ b/drivers/net/vxlan.c
>> >> @@ -2272,7 +2272,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
>> >> {
>> >> struct vxlan_net *vn = net_generic(net, vxlan_net_id);
>> >> struct vxlan_sock *vs;
>> >> - struct socket *sock;
>> >> + struct socket *sock = NULL;
>> >> struct sock *sk;
>> >> int rc = 0;
>> >> unsigned int h;
>> >
>> > This only happens with certain versions of Gcc which have buggy dependency
>> > analysis. It doesn't happen with Gcc 4.7, think it only shows up in 4.4.
>> > I would rather not fix the warning this way since it risks masking later bugs if this code ever changes.
>> Gcc version is 4.7.2 on my box, this warning took palce.
>> # gcc -v
>> Using built-in specs.
>> COLLECT_GCC=gcc
>> ...
>> gcc version 4.7.2 20120921 (Red Hat 4.7.2-2) (GCC)
>>
>>
>
> I dont see it on Debian 7.
> $ gcc -v
> Using built-in specs.
> COLLECT_GCC=/usr/bin/gcc-4.7.real
> COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
> Target: x86_64-linux-gnu
> Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
> Thread model: posix
> gcc version 4.7.2 (Debian 4.7.2-5)
--
Regards,
Zhi Yong Wu
^ permalink raw reply
* Re: [PATCH net-next 3/5] 6lowpan: use netdev_alloc_skb instead dev_alloc_skb
From: David Miller @ 2013-10-26 21:32 UTC (permalink / raw)
To: joe-6d6DIl74uiNBDgjK7y7TUQ
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-zigbee-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <1382767304.5595.1.camel@joe-AO722>
From: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
Date: Fri, 25 Oct 2013 23:01:44 -0700
> On Sat, 2013-10-26 at 01:42 -0400, David Miller wrote:
>> From: Alexander Aring <alex.aring-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Date: Thu, 24 Oct 2013 22:51:42 +0200
>>
>> > @@ -1127,12 +1127,12 @@ lowpan_fragment_xmit(struct sk_buff *skb, u8 *head,
>> >
>> > lowpan_raw_dump_inline(__func__, "6lowpan fragment header", head, hlen);
>> >
>> > - frag = dev_alloc_skb(hlen + mlen + plen + IEEE802154_MFR_SIZE);
>> > + frag = netdev_alloc_skb(skb->dev, hlen + mlen +
>> > + plen + IEEE802154_MFR_SIZE);
>>
>> Please indent this properly.
>>
>> It should be something like:
>>
>> frag = netdev_alloc_skb(skb->dev, hlen + mlen +
>> plen + IEEE802154_MFR_SIZE);
>
> Maybe better as:
>
> frag = netdev_alloc_skb(skb->dev,
> hlen + mlen + plen + IEEE802154_MFR_SIZE);
Either is fine with me.
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135991&iu=/4140/ostg.clktrk
^ permalink raw reply
* Re: [gpio:for-next 67/67] pch_gbe_main.c:undefined reference to `devm_gpio_request_one'
From: Darren Hart @ 2013-10-26 21:15 UTC (permalink / raw)
To: David Cohen
Cc: Linus Walleij, David S. Miller, netdev@vger.kernel.org,
Fengguang Wu, Alexandre Courbot, linux-gpio@vger.kernel.org
In-Reply-To: <1382819615.23829.16.camel@dvhart-mobl4.amr.corp.intel.com>
On Sat, 2013-10-26 at 21:33 +0100, Darren Hart wrote:
> On Fri, 2013-10-25 at 14:25 -0700, David Cohen wrote:
> > On 10/25/2013 02:21 PM, David Cohen wrote:
> > > Hi Linus,
> > >
> > > On 10/25/2013 03:49 AM, Linus Walleij wrote:
> > >> On Fri, Oct 25, 2013 at 12:41 PM, Linus Walleij
> > >> <linus.walleij@linaro.org> wrote:
> > >>
> > >>>> I wouldn't object to adding a dependency to GPIO_PCH and GPIOLIB
> > >>>> unconditionally for PCH_GBE as GPIO_PCH is the same chip... but I don't
> > >>>> know if David Miller would be amenable to that.
> > >>>
> > >>> Well we should probably just stick a dependency to GPIOLIB in there.
> > >>>
> > >>> - It #includes <linux/gpio.h>
> > >>> - It uses gpiolib functions to do something vital
> > >>>
> > >>> It was just happy that dummy versions were slotted in until now.
> > >>
> > >> ...or maybe I'm just confused now?
> > >>
> > >> Should we just add a static inline stub of devm_gpio_request_one()?
> > >
> > > I am not familiar with the HW. But checking the code, platform
> > > initialization should fail with a dummy devm_gpio_request_one()
> > > implementation. IMO it makes more sense to depend on GPIOLIB.
> >
> > Actually, forget about it. Despite driver_data->platform_init() may
> > return error, probe() never checks for it. I think the driver must be
> > fixed, but in meanwhile a static inline stub seems reasonable.
> >
>
> Ah, that's a problem, and one I created :/ I'm traveling a bit through
> Europe atm for the conferences. I will try and have a look on the planes
> and add a check.
Ah, now I remember. The situation is this. If there is a cable plugged
into the jack, the PHY will not go to sleep. If there isn't, there is a
good chance it will go to sleep before the driver initializes. If it is
asleep, the scan for the PHY will fail. If it isn't, the scan will work
correctly and the device will be properly setup. The code currently
displays a dev error:
ret = devm_gpio_request_one(&pdev->dev, gpio, flags,
"minnow_phy_reset");
if (ret) {
dev_err(&pdev->dev,
"ERR: Can't request PHY reset GPIO line '%d'\n", gpio);
But deliberately does not about the probe because there is a chance
things will work just fine. If they do not, the PHY detection code will
print display errors about a failure to communicate over RGMII, and the
device probe will fail from there.
This still seems like the correct approach to me. Does anyone disagree?
(we still need to sort out the GPIOLIB and GPIO_SCH dependency though of
course)
Thanks,
--
Darren Hart
Intel Open Source Technology Center
Yocto Project - Linux Kernel
^ permalink raw reply
* [PATCH 16/16] wl1251: Add sysfs file address for setting permanent mac address
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
Driver wl1251 generating mac address randomly at startup and there is no way to
set permanent mac address via SET_IEEE80211_PERM_ADDR. This patch export sysfs
file which can set permanent mac address by userspace helper program. Patch is
needed for devices which do not store mac address in internal wl1251 eeprom.
Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
drivers/net/wireless/ti/wl1251/main.c | 52 +++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 29625c2..91a009c 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -1375,6 +1375,46 @@ static const struct ieee80211_ops wl1251_ops = {
.get_survey = wl1251_op_get_survey,
};
+static ssize_t wl1251_sysfs_show_address(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ ssize_t len;
+
+ /* FIXME: what's the maximum length of buf? page size?*/
+ len = 500;
+
+ len = snprintf(buf, len, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+ wl->mac_addr[0], wl->mac_addr[1], wl->mac_addr[2],
+ wl->mac_addr[3], wl->mac_addr[4], wl->mac_addr[5]);
+
+ return len;
+}
+
+static ssize_t wl1251_sysfs_store_address(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ unsigned int addr[6];
+ int ret, i;
+
+ ret = sscanf(buf, "%2x:%2x:%2x:%2x:%2x:%2x\n",
+ &addr[0], &addr[1], &addr[2],
+ &addr[3], &addr[4], &addr[5]);
+
+ if (ret != 6)
+ return -EINVAL;
+
+ for (i = 0; i < 6; i++)
+ wl->mac_addr[i] = addr[i] & 0xff;
+
+ SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+ return count;
+}
+
static ssize_t wl1251_sysfs_show_tx_mgmt_frm_rate(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1584,6 +1624,10 @@ out:
return count;
}
+static DEVICE_ATTR(address, S_IRUGO | S_IWUSR,
+ wl1251_sysfs_show_address,
+ wl1251_sysfs_store_address);
+
static DEVICE_ATTR(tx_mgmt_frm_rate, S_IRUGO | S_IWUSR,
wl1251_sysfs_show_tx_mgmt_frm_rate,
wl1251_sysfs_store_tx_mgmt_frm_rate);
@@ -1728,6 +1772,14 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
}
dev_set_drvdata(&wl1251_device.dev, wl);
+ /* Create sysfs file address */
+ ret = device_create_file(&wl1251_device.dev,
+ &dev_attr_address);
+ if (ret < 0) {
+ wl1251_error("failed to create sysfs file address");
+ goto out;
+ }
+
/* Create sysfs file tx_mgmt_frm_rate */
ret = device_create_file(&wl1251_device.dev,
&dev_attr_tx_mgmt_frm_rate);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 15/16] wl1251: Add sysfs file tx_mgmt_frm_rate for setting rate
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
This patch was extracted from Maemo 2.6.28 kernel
Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
drivers/net/wireless/ti/wl1251/main.c | 152 +++++++++++++++++++++++++++++++++
1 file changed, 152 insertions(+)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 7b9efc8..29625c2 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -1375,6 +1375,147 @@ static const struct ieee80211_ops wl1251_ops = {
.get_survey = wl1251_op_get_survey,
};
+static ssize_t wl1251_sysfs_show_tx_mgmt_frm_rate(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ ssize_t len;
+ int val;
+
+ /* FIXME: what's the maximum length of buf? page size?*/
+ len = 500;
+
+ switch (wl->tx_mgmt_frm_rate) {
+ /* skip 1 and 12 Mbps because they have same value 0x0a */
+ case RATE_2MBPS:
+ val = 20;
+ break;
+ case RATE_5_5MBPS:
+ val = 55;
+ break;
+ case RATE_11MBPS:
+ val = 110;
+ break;
+ case RATE_6MBPS:
+ val = 60;
+ break;
+ case RATE_9MBPS:
+ val = 90;
+ break;
+ case RATE_12MBPS:
+ val = 120;
+ break;
+ case RATE_18MBPS:
+ val = 180;
+ break;
+ case RATE_24MBPS:
+ val = 240;
+ break;
+ case RATE_36MBPS:
+ val = 360;
+ break;
+ case RATE_48MBPS:
+ val = 480;
+ break;
+ case RATE_54MBPS:
+ val = 540;
+ break;
+ default:
+ val = 10;
+ }
+
+ /* for 1 and 12 Mbps we have to check the modulation */
+ if (wl->tx_mgmt_frm_rate == RATE_1MBPS) {
+ switch (wl->tx_mgmt_frm_rate) {
+ case CCK_LONG:
+ val = 10;
+ break;
+ case OFDM:
+ val = 120;
+ break;
+ default:
+ val = 10;
+ break;
+ }
+ }
+ len = snprintf(buf, len, "%d", val);
+
+ return len;
+}
+
+static ssize_t wl1251_sysfs_store_tx_mgmt_frm_rate(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct wl1251 *wl = dev_get_drvdata(dev);
+ unsigned long res;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &res);
+
+ if (ret < 0) {
+ wl1251_warning("incorrect value written to tx_mgmt_frm_rate");
+ return 0;
+ }
+
+ switch (res) {
+ case 10:
+ wl->tx_mgmt_frm_rate = RATE_1MBPS;
+ wl->tx_mgmt_frm_mod = CCK_LONG;
+ break;
+ case 20:
+ wl->tx_mgmt_frm_rate = RATE_2MBPS;
+ wl->tx_mgmt_frm_mod = CCK_LONG;
+ break;
+ case 55:
+ wl->tx_mgmt_frm_rate = RATE_5_5MBPS;
+ wl->tx_mgmt_frm_mod = CCK_LONG;
+ break;
+ case 110:
+ wl->tx_mgmt_frm_rate = RATE_11MBPS;
+ wl->tx_mgmt_frm_mod = CCK_LONG;
+ break;
+ case 60:
+ wl->tx_mgmt_frm_rate = RATE_6MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ case 90:
+ wl->tx_mgmt_frm_rate = RATE_9MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ case 120:
+ wl->tx_mgmt_frm_rate = RATE_12MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ case 180:
+ wl->tx_mgmt_frm_rate = RATE_18MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ case 240:
+ wl->tx_mgmt_frm_rate = RATE_24MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ case 360:
+ wl->tx_mgmt_frm_rate = RATE_36MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ case 480:
+ wl->tx_mgmt_frm_rate = RATE_48MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ case 540:
+ wl->tx_mgmt_frm_rate = RATE_54MBPS;
+ wl->tx_mgmt_frm_mod = OFDM;
+ break;
+ default:
+ wl1251_warning("incorrect value written to tx_mgmt_frm_rate");
+ return 0;
+ }
+
+ return count;
+}
+
static ssize_t wl1251_sysfs_show_bt_coex_mode(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1443,6 +1584,10 @@ out:
return count;
}
+static DEVICE_ATTR(tx_mgmt_frm_rate, S_IRUGO | S_IWUSR,
+ wl1251_sysfs_show_tx_mgmt_frm_rate,
+ wl1251_sysfs_store_tx_mgmt_frm_rate);
+
static DEVICE_ATTR(bt_coex_mode, S_IRUGO | S_IWUSR,
wl1251_sysfs_show_bt_coex_mode,
wl1251_sysfs_store_bt_coex_mode);
@@ -1583,6 +1728,13 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
}
dev_set_drvdata(&wl1251_device.dev, wl);
+ /* Create sysfs file tx_mgmt_frm_rate */
+ ret = device_create_file(&wl1251_device.dev,
+ &dev_attr_tx_mgmt_frm_rate);
+ if (ret < 0) {
+ wl1251_error("failed to create sysfs file tx_mgmt_frm_rate");
+ goto out;
+ }
/* Create sysfs file to control bt coex state */
ret = device_create_file(&wl1251_device.dev, &dev_attr_bt_coex_mode);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 14/16] wl1251: add nvs file name to module firmware list
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
drivers/net/wireless/ti/wl1251/main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index f054741..7b9efc8 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -1709,3 +1709,4 @@ MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
MODULE_FIRMWARE(WL1251_FW_NAME);
+MODULE_FIRMWARE(WL1251_NVS_NAME);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 13/16] wl1251: enforce changed hw encryption support on monitor state change
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, freemangordon-uiMcrn6V0Vs,
aaro.koskinen-X3B1VOXEql0, pavel-+ZI9xUNit7I, sre-GFxCN5SEZAc,
joni.lapilainen-Re5JQEeQqe8AvxtiuMwx3w,
pali.rohar-Re5JQEeQqe8AvxtiuMwx3w, David Gnedt
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: David Gnedt <david.gnedt-rFfgOQFw6VLk7+2FdBfRIA@public.gmane.org>
The firmware doesn't support per packet encryption selection, so disable hw
encryption support completly while a monitor interface is present to support
injection of packets (which shouldn't get encrypted by hw).
To enforce the changed hw encryption support force a disassociation on
non-monitor interfaces.
For disassociation a workaround using hw connection monitor is employed,
which temporary enables hw connection manager flag.
Signed-off-by: David Gnedt <david.gnedt-rFfgOQFw6VLk7+2FdBfRIA@public.gmane.org>
---
drivers/net/wireless/ti/wl1251/main.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 174f403..f054741 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -685,6 +685,16 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
wl->power_level = conf->power_level;
}
+ /*
+ * Tell stack that connection is lost because hw encryption isn't
+ * supported in monitor mode.
+ * XXX This requires temporary enabling the hw connection monitor flag
+ */
+ if ((changed & IEEE80211_CONF_CHANGE_MONITOR) && wl->vif) {
+ wl->hw->flags |= IEEE80211_HW_CONNECTION_MONITOR;
+ ieee80211_connection_loss(wl->vif);
+ }
+
out_sleep:
wl1251_ps_elp_sleep(wl);
@@ -1116,6 +1126,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ASSOC) {
+ /* XXX Disable temporary enabled hw connection monitor flag */
+ wl->hw->flags &= ~IEEE80211_HW_CONNECTION_MONITOR;
+
if (bss_conf->assoc) {
wl->beacon_int = bss_conf->beacon_int;
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 12/16] wl1251: disable retry and ACK policy for injected packets
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar,
David Gnedt
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
From: David Gnedt <david.gnedt@davizone.at>
Set the retry limit to 0 and disable the ACK policy for injected packets.
Signed-off-by: David Gnedt <david.gnedt@davizone.at>
---
drivers/net/wireless/ti/wl1251/acx.c | 8 +++++++-
drivers/net/wireless/ti/wl1251/tx.c | 7 ++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index 14da6de..f98d46f 100644
--- a/drivers/net/wireless/ti/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
@@ -943,12 +943,18 @@ int wl1251_acx_rate_policies(struct wl1251 *wl)
}
/* configure one default (one-size-fits-all) rate class */
- acx->rate_class_cnt = 1;
+ acx->rate_class_cnt = 2;
acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
acx->rate_class[0].aflags = 0;
+ /* no-retry rate class */
+ acx->rate_class[1].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
+ acx->rate_class[1].short_retry_limit = 0;
+ acx->rate_class[1].long_retry_limit = 0;
+ acx->rate_class[1].aflags = 0;
+
ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
if (ret < 0) {
wl1251_warning("Setting of rate policies failed: %d", ret);
diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
index 1de4ccb..e559bc4 100644
--- a/drivers/net/wireless/ti/wl1251/tx.c
+++ b/drivers/net/wireless/ti/wl1251/tx.c
@@ -90,8 +90,12 @@ static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr,
/* 802.11 packets */
tx_hdr->control.packet_type = 0;
- if (control->flags & IEEE80211_TX_CTL_NO_ACK)
+ /* Also disable retry and ACK policy for injected packets */
+ if ((control->flags & IEEE80211_TX_CTL_NO_ACK) ||
+ (control->flags & IEEE80211_TX_CTL_INJECTED)) {
+ tx_hdr->control.rate_policy = 1;
tx_hdr->control.ack_policy = 1;
+ }
tx_hdr->control.tx_complete = 1;
@@ -414,6 +418,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl,
info = IEEE80211_SKB_CB(skb);
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
(result->status == TX_SUCCESS))
info->flags |= IEEE80211_TX_STAT_ACK;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 11/16] wl1251: enable tx path in monitor mode if necessary for packet injection
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar,
David Gnedt
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
From: David Gnedt <david.gnedt@davizone.at>
If necessary enable the tx path in monitor mode for packet injection using
the JOIN command with BSS_TYPE_STA_BSS and zero BSSID.
Signed-off-by: David Gnedt <david.gnedt@davizone.at>
---
drivers/net/wireless/ti/wl1251/main.c | 5 +++++
drivers/net/wireless/ti/wl1251/tx.c | 17 +++++++++++++++++
drivers/net/wireless/ti/wl1251/wl1251.h | 1 +
3 files changed, 23 insertions(+)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 7e6b6d1..174f403 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -487,6 +487,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
wl->rssi_thold = 0;
wl->channel = WL1251_DEFAULT_CHANNEL;
wl->monitor_present = false;
+ wl->joined = false;
wl1251_debugfs_reset(wl);
@@ -546,6 +547,7 @@ static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&wl->mutex);
wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
wl->vif = NULL;
+ memset(wl->bssid, 0, ETH_ALEN);
mutex_unlock(&wl->mutex);
}
@@ -619,6 +621,7 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
* at firmware level.
*/
if (wl->vif == NULL) {
+ wl->joined = false;
ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1);
} else {
ret = wl1251_join(wl, wl->bss_type, wl->channel,
@@ -1610,7 +1613,9 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
wl->channel = WL1251_DEFAULT_CHANNEL;
wl->monitor_present = false;
+ wl->joined = false;
wl->scanning = false;
+ wl->bss_type = MAX_BSS_TYPE;
wl->default_key = 0;
wl->listen_int = 1;
wl->rx_counter = 0;
diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
index 3cc82fd..1de4ccb 100644
--- a/drivers/net/wireless/ti/wl1251/tx.c
+++ b/drivers/net/wireless/ti/wl1251/tx.c
@@ -28,6 +28,7 @@
#include "tx.h"
#include "ps.h"
#include "io.h"
+#include "event.h"
static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
{
@@ -298,6 +299,22 @@ static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
}
}
+ /* Enable tx path in monitor mode for packet injection */
+ if ((wl->vif == NULL) && !wl->joined) {
+ ret = wl1251_cmd_join(wl, BSS_TYPE_STA_BSS, wl->channel,
+ wl->beacon_int, wl->dtim_period);
+ if (ret < 0)
+ wl1251_warning("join failed");
+ else {
+ ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID,
+ 100);
+ if (ret < 0)
+ wl1251_warning("join timeout");
+ else
+ wl->joined = true;
+ }
+ }
+
ret = wl1251_tx_path_status(wl);
if (ret < 0)
return ret;
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index e478e61..1bdf779 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -311,6 +311,7 @@ struct wl1251 {
u8 listen_int;
int channel;
bool monitor_present;
+ bool joined;
void *target_mem_map;
struct acx_data_path_params_resp *data_path;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 10/16] wl1251: fix channel switching in monitor mode
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar,
David Gnedt
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
From: David Gnedt <david.gnedt@davizone.at>
Use the ENABLE_RX command for channel switching when no interface is present
(monitor mode only).
The advantage of ENABLE_RX is that it leaves the tx data path disabled in
firmware, whereas the usual JOIN command seems to transmit some frames at
firmware level.
Signed-off-by: David Gnedt <david.gnedt@davizone.at>
---
drivers/net/wireless/ti/wl1251/main.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 62cb374..7e6b6d1 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -611,8 +611,19 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
if (channel != wl->channel) {
wl->channel = channel;
- ret = wl1251_join(wl, wl->bss_type, wl->channel,
- wl->beacon_int, wl->dtim_period);
+ /*
+ * Use ENABLE_RX command for channel switching when no
+ * interface is present (monitor mode only).
+ * This leaves the tx path disabled in firmware, whereas
+ * the usual JOIN command seems to transmit some frames
+ * at firmware level.
+ */
+ if (wl->vif == NULL) {
+ ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1);
+ } else {
+ ret = wl1251_join(wl, wl->bss_type, wl->channel,
+ wl->beacon_int, wl->dtim_period);
+ }
if (ret < 0)
goto out_sleep;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 09/16] wl1251: disable power saving in monitor mode
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar,
David Gnedt
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
From: David Gnedt <david.gnedt@davizone.at>
Force power saving off while monitor interface is present.
Signed-off-by: David Gnedt <david.gnedt@davizone.at>
---
drivers/net/wireless/ti/wl1251/main.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 727f2ee..62cb374 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -617,7 +617,8 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
goto out_sleep;
}
- if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
+ if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested &&
+ !wl->monitor_present) {
wl1251_debug(DEBUG_PSM, "psm enabled");
wl->psm_requested = true;
@@ -633,8 +634,8 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
if (ret < 0)
goto out_sleep;
- } else if (!(conf->flags & IEEE80211_CONF_PS) &&
- wl->psm_requested) {
+ } else if ((!(conf->flags & IEEE80211_CONF_PS) || wl->monitor_present)
+ && wl->psm_requested) {
wl1251_debug(DEBUG_PSM, "psm disabled");
wl->psm_requested = false;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 08/16] wl1251: implement multicast address filtering
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless, netdev, linux-kernel, freemangordon,
aaro.koskinen, pavel, sre, joni.lapilainen, pali.rohar,
David Gnedt
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar@gmail.com>
From: David Gnedt <david.gnedt@davizone.at>
Port multicast address filtering from wl1271 driver.
It sets up the hardware multicast address filter in configure_filter() with
addresses supplied through prepare_multicast().
Signed-off-by: David Gnedt <david.gnedt@davizone.at>
---
drivers/net/wireless/ti/wl1251/acx.c | 9 ++---
drivers/net/wireless/ti/wl1251/acx.h | 9 ++---
drivers/net/wireless/ti/wl1251/init.c | 2 +-
drivers/net/wireless/ti/wl1251/main.c | 57 +++++++++++++++++++++++++++++--
drivers/net/wireless/ti/wl1251/wl1251.h | 1 +
5 files changed, 67 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index e79636f..14da6de 100644
--- a/drivers/net/wireless/ti/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
@@ -408,7 +408,8 @@ out:
return ret;
}
-int wl1251_acx_group_address_tbl(struct wl1251 *wl)
+int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable,
+ void *mc_list, u32 mc_list_len)
{
struct acx_dot11_grp_addr_tbl *acx;
int ret;
@@ -422,9 +423,9 @@ int wl1251_acx_group_address_tbl(struct wl1251 *wl)
}
/* MAC filtering */
- acx->enabled = 0;
- acx->num_groups = 0;
- memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+ acx->enabled = enable;
+ acx->num_groups = mc_list_len;
+ memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
acx, sizeof(*acx));
diff --git a/drivers/net/wireless/ti/wl1251/acx.h b/drivers/net/wireless/ti/wl1251/acx.h
index bea2e67..820573c 100644
--- a/drivers/net/wireless/ti/wl1251/acx.h
+++ b/drivers/net/wireless/ti/wl1251/acx.h
@@ -350,8 +350,8 @@ struct acx_slot {
} __packed;
-#define ADDRESS_GROUP_MAX (8)
-#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX)
+#define ACX_MC_ADDRESS_GROUP_MAX (8)
+#define ACX_MC_ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX)
struct acx_dot11_grp_addr_tbl {
struct acx_header header;
@@ -359,7 +359,7 @@ struct acx_dot11_grp_addr_tbl {
u8 enabled;
u8 num_groups;
u8 pad[2];
- u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+ u8 mac_table[ACX_MC_ADDRESS_GROUP_MAX_LEN];
} __packed;
@@ -1464,7 +1464,8 @@ int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time);
int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter);
int wl1251_acx_pd_threshold(struct wl1251 *wl);
int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time);
-int wl1251_acx_group_address_tbl(struct wl1251 *wl);
+int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable,
+ void *mc_list, u32 mc_list_len);
int wl1251_acx_service_period_timeout(struct wl1251 *wl);
int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold);
int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter);
diff --git a/drivers/net/wireless/ti/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c
index 92de289..f8a2ea9 100644
--- a/drivers/net/wireless/ti/wl1251/init.c
+++ b/drivers/net/wireless/ti/wl1251/init.c
@@ -127,7 +127,7 @@ int wl1251_hw_init_phy_config(struct wl1251 *wl)
if (ret < 0)
return ret;
- ret = wl1251_acx_group_address_tbl(wl);
+ ret = wl1251_acx_group_address_tbl(wl, true, NULL, 0);
if (ret < 0)
return ret;
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index c6e2591..727f2ee 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -29,6 +29,7 @@
#include <linux/vmalloc.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/netdevice.h>
#include "wl1251.h"
#include "wl12xx_80211.h"
@@ -678,6 +679,44 @@ out:
return ret;
}
+struct wl1251_filter_params {
+ bool enabled;
+ int mc_list_length;
+ u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
+};
+
+static u64 wl1251_op_prepare_multicast(struct ieee80211_hw *hw,
+ struct netdev_hw_addr_list *mc_list)
+{
+ struct wl1251_filter_params *fp;
+ struct netdev_hw_addr *ha;
+ struct wl1251 *wl = hw->priv;
+
+ if (unlikely(wl->state == WL1251_STATE_OFF))
+ return 0;
+
+ fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
+ if (!fp) {
+ wl1251_error("Out of memory setting filters.");
+ return 0;
+ }
+
+ /* update multicast filtering parameters */
+ fp->mc_list_length = 0;
+ if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) {
+ fp->enabled = false;
+ } else {
+ fp->enabled = true;
+ netdev_hw_addr_list_for_each(ha, mc_list) {
+ memcpy(fp->mc_list[fp->mc_list_length],
+ ha->addr, ETH_ALEN);
+ fp->mc_list_length++;
+ }
+ }
+
+ return (u64)(unsigned long)fp;
+}
+
#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
FIF_ALLMULTI | \
FIF_FCSFAIL | \
@@ -688,8 +727,9 @@ out:
static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
unsigned int changed,
- unsigned int *total,u64 multicast)
+ unsigned int *total, u64 multicast)
{
+ struct wl1251_filter_params *fp = (void *)(unsigned long)multicast;
struct wl1251 *wl = hw->priv;
int ret;
@@ -698,9 +738,11 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
*total &= WL1251_SUPPORTED_FILTERS;
changed &= WL1251_SUPPORTED_FILTERS;
- if (changed == 0)
+ if (changed == 0) {
/* no filters which we support changed */
+ kfree(fp);
return;
+ }
mutex_lock(&wl->mutex);
@@ -737,6 +779,15 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
if (ret < 0)
goto out;
+ if (*total & FIF_ALLMULTI || *total & FIF_PROMISC_IN_BSS)
+ ret = wl1251_acx_group_address_tbl(wl, false, NULL, 0);
+ else if (fp)
+ ret = wl1251_acx_group_address_tbl(wl, fp->enabled,
+ fp->mc_list,
+ fp->mc_list_length);
+ if (ret < 0)
+ goto out;
+
/* send filters to firmware */
wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
@@ -744,6 +795,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
out:
mutex_unlock(&wl->mutex);
+ kfree(fp);
}
/* HW encryption */
@@ -1284,6 +1336,7 @@ static const struct ieee80211_ops wl1251_ops = {
.add_interface = wl1251_op_add_interface,
.remove_interface = wl1251_op_remove_interface,
.config = wl1251_op_config,
+ .prepare_multicast = wl1251_op_prepare_multicast,
.configure_filter = wl1251_op_configure_filter,
.tx = wl1251_op_tx,
.set_key = wl1251_op_set_key,
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 750e510..e478e61 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -93,6 +93,7 @@ enum {
} while (0)
#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
+ CFG_MC_FILTER_EN | \
CFG_BSSID_FILTER_EN)
#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \
--
1.7.10.4
^ permalink raw reply related
* [PATCH 07/16] wl1251: configure hardware en-/decryption for monitor mode
From: Pali Rohár @ 2013-10-26 20:34 UTC (permalink / raw)
To: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, freemangordon-uiMcrn6V0Vs,
aaro.koskinen-X3B1VOXEql0, pavel-+ZI9xUNit7I, sre-GFxCN5SEZAc,
joni.lapilainen-Re5JQEeQqe8AvxtiuMwx3w,
pali.rohar-Re5JQEeQqe8AvxtiuMwx3w, David Gnedt
In-Reply-To: <1382819655-30430-1-git-send-email-pali.rohar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: David Gnedt <david.gnedt-rFfgOQFw6VLk7+2FdBfRIA@public.gmane.org>
Disable hardware encryption (DF_ENCRYPTION_DISABLE) and decryption
(DF_SNIFF_MODE_ENABLE) via wl1251_acx_feature_cfg while monitor interface is
present.
Signed-off-by: David Gnedt <david.gnedt-rFfgOQFw6VLk7+2FdBfRIA@public.gmane.org>
---
drivers/net/wireless/ti/wl1251/acx.c | 6 +++---
drivers/net/wireless/ti/wl1251/acx.h | 2 +-
drivers/net/wireless/ti/wl1251/init.c | 2 +-
drivers/net/wireless/ti/wl1251/main.c | 34 ++++++++++++++++++++++++++-----
drivers/net/wireless/ti/wl1251/rx.c | 2 +-
drivers/net/wireless/ti/wl1251/tx.c | 3 +++
drivers/net/wireless/ti/wl1251/wl1251.h | 1 +
7 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index 9295090..e79636f 100644
--- a/drivers/net/wireless/ti/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
@@ -209,7 +209,7 @@ out:
return ret;
}
-int wl1251_acx_feature_cfg(struct wl1251 *wl)
+int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options)
{
struct acx_feature_config *feature;
int ret;
@@ -222,8 +222,8 @@ int wl1251_acx_feature_cfg(struct wl1251 *wl)
goto out;
}
- /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
- feature->data_flow_options = 0;
+ /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE can be set */
+ feature->data_flow_options = data_flow_options;
feature->options = 0;
ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
diff --git a/drivers/net/wireless/ti/wl1251/acx.h b/drivers/net/wireless/ti/wl1251/acx.h
index 4444cd0..bea2e67 100644
--- a/drivers/net/wireless/ti/wl1251/acx.h
+++ b/drivers/net/wireless/ti/wl1251/acx.h
@@ -1455,7 +1455,7 @@ int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth);
int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len);
int wl1251_acx_tx_power(struct wl1251 *wl, int power);
-int wl1251_acx_feature_cfg(struct wl1251 *wl);
+int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options);
int wl1251_acx_mem_map(struct wl1251 *wl,
struct acx_header *mem_map, size_t len);
int wl1251_acx_data_path_params(struct wl1251 *wl,
diff --git a/drivers/net/wireless/ti/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c
index 424ce01..92de289 100644
--- a/drivers/net/wireless/ti/wl1251/init.c
+++ b/drivers/net/wireless/ti/wl1251/init.c
@@ -33,7 +33,7 @@ int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
{
int ret;
- ret = wl1251_acx_feature_cfg(wl);
+ ret = wl1251_acx_feature_cfg(wl, 0);
if (ret < 0) {
wl1251_warning("couldn't set feature config");
return ret;
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 9752745..c6e2591 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -485,6 +485,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
wl->rssi_thold = 0;
wl->channel = WL1251_DEFAULT_CHANNEL;
+ wl->monitor_present = false;
wl1251_debugfs_reset(wl);
@@ -577,8 +578,10 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
channel = ieee80211_frequency_to_channel(
conf->chandef.chan->center_freq);
- wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+ wl1251_debug(DEBUG_MAC80211,
+ "mac80211 config ch %d monitor %s psm %s power %d",
channel,
+ conf->flags & IEEE80211_CONF_MONITOR ? "on" : "off",
conf->flags & IEEE80211_CONF_PS ? "on" : "off",
conf->power_level);
@@ -588,6 +591,22 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
if (ret < 0)
goto out;
+ if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+ u32 mode;
+
+ if (conf->flags & IEEE80211_CONF_MONITOR) {
+ wl->monitor_present = true;
+ mode = DF_SNIFF_MODE_ENABLE | DF_ENCRYPTION_DISABLE;
+ } else {
+ wl->monitor_present = false;
+ mode = 0;
+ }
+
+ ret = wl1251_acx_feature_cfg(wl, mode);
+ if (ret < 0)
+ goto out_sleep;
+ }
+
if (channel != wl->channel) {
wl->channel = channel;
@@ -804,12 +823,12 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
mutex_lock(&wl->mutex);
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out_unlock;
-
switch (cmd) {
case SET_KEY:
+ if (wl->monitor_present) {
+ ret = -EOPNOTSUPP;
+ goto out_unlock;
+ }
wl_cmd->key_action = KEY_ADD_OR_REPLACE;
break;
case DISABLE_KEY:
@@ -820,6 +839,10 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
break;
}
+ ret = wl1251_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out_unlock;
+
ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
if (ret < 0) {
wl1251_error("Set KEY type failed");
@@ -1521,6 +1544,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
wl->channel = WL1251_DEFAULT_CHANNEL;
+ wl->monitor_present = false;
wl->scanning = false;
wl->default_key = 0;
wl->listen_int = 1;
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c
index 23289d4..123c4bb 100644
--- a/drivers/net/wireless/ti/wl1251/rx.c
+++ b/drivers/net/wireless/ti/wl1251/rx.c
@@ -83,7 +83,7 @@ static void wl1251_rx_status(struct wl1251 *wl,
status->flag |= RX_FLAG_MACTIME_START;
- if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
+ if (!wl->monitor_present && (desc->flags & RX_DESC_ENCRYPTION_MASK)) {
status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
index 28121c5..3cc82fd 100644
--- a/drivers/net/wireless/ti/wl1251/tx.c
+++ b/drivers/net/wireless/ti/wl1251/tx.c
@@ -287,6 +287,9 @@ static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
info = IEEE80211_SKB_CB(skb);
if (info->control.hw_key) {
+ if (unlikely(wl->monitor_present))
+ return -1;
+
idx = info->control.hw_key->hw_key_idx;
if (unlikely(wl->default_key != idx)) {
ret = wl1251_acx_default_key(wl, idx);
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 7cd1bac..750e510 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -309,6 +309,7 @@ struct wl1251 {
u8 bss_type;
u8 listen_int;
int channel;
+ bool monitor_present;
void *target_mem_map;
struct acx_data_path_params_resp *data_path;
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox