* Re: [PATCH] NFC: only put local on destruction if it was created before
From: Samuel Ortiz @ 2012-06-25 17:17 UTC (permalink / raw)
To: Sasha Levin
Cc: lauro.venancio, aloisio.almeida, linville, davej, linux-wireless,
netdev, linux-kernel
In-Reply-To: <1339531699-7377-1-git-send-email-levinsasha928@gmail.com>
Hi Sasha,
On Tue, Jun 12, 2012 at 10:08:19PM +0200, Sasha Levin wrote:
> Not having 'local' is a valid case when a socket was created but never
> bound or connected to anything, so avoid putting 'local' if it was
> never created.
>
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> net/nfc/llcp/sock.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
> index 2c0b317..54daa10 100644
> --- a/net/nfc/llcp/sock.c
> +++ b/net/nfc/llcp/sock.c
> @@ -710,7 +710,8 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
>
> sock->parent = NULL;
>
> - nfc_llcp_local_put(sock->local);
> + if (sock->local)
> + nfc_llcp_local_put(sock->local);
nfc_llcp_local_put() already checks for its argument being NULL or not.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply
* Re: [PATCH] NFC: only put local on destruction if it was created before
From: Sasha Levin @ 2012-06-25 17:15 UTC (permalink / raw)
To: Samuel Ortiz
Cc: lauro.venancio, aloisio.almeida, linville, davej, linux-wireless,
netdev, linux-kernel
In-Reply-To: <20120625171738.GC16275@sortiz-mobl>
On Mon, 2012-06-25 at 19:17 +0200, Samuel Ortiz wrote:
> Hi Sasha,
>
> On Tue, Jun 12, 2012 at 10:08:19PM +0200, Sasha Levin wrote:
> > Not having 'local' is a valid case when a socket was created but never
> > bound or connected to anything, so avoid putting 'local' if it was
> > never created.
> >
> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> > ---
> > net/nfc/llcp/sock.c | 3 ++-
> > 1 files changed, 2 insertions(+), 1 deletions(-)
> >
> > diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
> > index 2c0b317..54daa10 100644
> > --- a/net/nfc/llcp/sock.c
> > +++ b/net/nfc/llcp/sock.c
> > @@ -710,7 +710,8 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
> >
> > sock->parent = NULL;
> >
> > - nfc_llcp_local_put(sock->local);
> > + if (sock->local)
> > + nfc_llcp_local_put(sock->local);
> nfc_llcp_local_put() already checks for its argument being NULL or not.
nfc_llcp_local_put() triggers a warning in this case as well, which
means that this code path shouldn't be happening.
Should we remove the WARN_ON from nfc_llcp_local_put() instead?
^ permalink raw reply
* Re: [PATCH] net: nfc: fix panic in accept()
From: Samuel Ortiz @ 2012-06-25 17:15 UTC (permalink / raw)
To: Eric Dumazet
Cc: Sasha Levin, Dave Jones, David Miller, lauro.venancio,
aloisio.almeida, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless
In-Reply-To: <1340639612.10893.84.camel@edumazet-glaptop>
Hi Eric,
On Mon, Jun 25, 2012 at 05:53:32PM +0200, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Sasha Levin reported following panic :
I applied a similar patch, more consistent with the rest of the NFC socket
code, still with you as the author. See here:
http://git.kernel.org/?p=linux/kernel/git/sameo/nfc-3.0.git;a=commit;h=631c301f20558525a641fadffc0126affd3dc4a4
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply
* RE: Linux 3.4.2 doesn't detect Intel 82579V on Supermicro X9SCL-F
From: Allan, Bruce W @ 2012-06-25 17:13 UTC (permalink / raw)
To: Denys Fedoryshchenko, Kirsher, Jeffrey T, Brandeburg, Jesse,
Wyborny, Carolyn, Skidmore, Donald C, Rose, Gregory V,
Waskiewicz Jr, Peter P, Duyck, Alexander H, Ronciak, John,
e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <7d89df63ac6b7f801f8b8fb69d0c1b14@visp.net.lb>
> -----Original Message-----
> From: Denys Fedoryshchenko [mailto:denys@visp.net.lb]
> Sent: Saturday, June 23, 2012 1:05 AM
> To: Kirsher, Jeffrey T; Brandeburg, Jesse; Allan, Bruce W; Wyborny,
> Carolyn; Skidmore, Donald C; Rose, Gregory V; Waskiewicz Jr, Peter P;
> Duyck, Alexander H; Ronciak, John; e1000-devel@lists.sourceforge.net;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Linux 3.4.2 doesn't detect Intel 82579V on Supermicro X9SCL-F
>
> I have motherboard X9SCL-F with two onboard network cards, one of them
> are not detected.
> First i notice that on Ubuntu, now i tried also vanilla 3.4.2, on same
> motherboard model, but different server.
>
> 00:19.0 Ethernet controller: Intel Corporation 82579V Gigabit Network
> Connection (rev 05)
> 02:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network
> Connection
>
> Particular adapter that are not working:
>
> 00:19.0 Ethernet controller: Intel Corporation 82579V Gigabit Network
> Connection (rev 05)
> Subsystem: Intel Corporation Device 0000
> Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop-
> ParErr+ Stepping- SERR+ FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast
> >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
> Interrupt: pin A routed to IRQ 20
> Region 0: Memory at f7a00000 (32-bit, non-prefetchable)
> [size=128K]
> Region 1: Memory at f7a23000 (32-bit, non-prefetchable)
> [size=4K]
> Region 2: I/O ports at f020 [size=32]
> Capabilities: [c8] Power Management version 2
> Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA
> PME(D0+,D1-,D2-,D3hot+,D3cold+)
> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=1
> PME-
> Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+
> Address: 00000000fee00378 Data: 0000
> Capabilities: [e0] PCI Advanced Features
> AFCap: TP+ FLR+
> AFCtrl: FLR-
> AFStatus: TP-
> Kernel modules: e1000e
>
> corresponding log entries:
> [ 3.189176] e1000e: Intel(R) PRO/1000 Network Driver - 1.5.1-k
> [ 3.197950] e1000e: Copyright(c) 1999 - 2011 Intel Corporation.
> [ 3.206540] md: raid0 personality registered for level 0
> [ 3.206693] e1000e 0000:00:19.0: PCI INT A -> GSI 20 (level, low) ->
> IRQ 20
> [ 3.206723] e1000e 0000:00:19.0: setting latency timer to 64
> [ 3.207412] e1000e 0000:00:19.0: irq 42 for MSI/MSI-X
> [ 3.224410] input: Winbond Electronics Corp Hermon USB hidmouse Device
> as
> /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/input/input2
> [ 3.241969] md: raid1 personality registered for level 1
> [ 3.242538] generic-usb 0003:0557:2221.0001: input,hidraw0: USB HID
> v1.00 Mouse [Winbond Electronics Corp Hermon USB hidmouse Device] on
> usb-0000:00:1a.0-1.2/input0
> [ 3.243563] input: Winbond Electronics Corp Hermon USB hidmouse Device
> as
> /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.1/input/input3
> [ 3.243978] generic-usb 0003:0557:2221.0002: input,hidraw1: USB HID
> v1.00 Keyboard [Winbond Electronics Corp Hermon USB hidmouse Device]
> on
> usb-0000:00:1a.0-1.2/input1
> [ 3.243988] usbcore: registered new interface driver usbhid
> [ 3.243989] usbhid: USB HID core driver
> [ 3.271808] e1000e 0000:00:19.0: PCI INT A disabled
> [ 3.271813] e1000e: probe of 0000:00:19.0 failed with error -3
> [ 3.271821] e1000e 0000:02:00.0: Disabling ASPM L0s
> [ 3.272000] e1000e 0000:02:00.0: PCI INT A -> GSI 16 (level, low) ->
> IRQ 16
> [ 3.272082] e1000e 0000:02:00.0: setting latency timer to 64
> [ 3.381646] e1000e 0000:02:00.0: irq 42 for MSI/MSI-X
> [ 3.381652] e1000e 0000:02:00.0: irq 43 for MSI/MSI-X
> [ 3.381658] e1000e 0000:02:00.0: irq 44 for MSI/MSI-X
> [ 3.382503] async_tx: api initialized (async)
>
> root@central:~# ethtool -i eth0
> driver: e1000e
> version: 1.5.1-k
> firmware-version: 2.1-2
> bus-info: 0000:02:00.0
> supports-statistics: yes
> supports-test: yes
> supports-eeprom-access: yes
> supports-register-dump: yes
> root@central:~# ethtool -i eth1
> Cannot get driver information: No such device
> ---
> AlsaDevices:
> total 0
> crw-rw---T 1 root audio 116, 1 Jun 17 13:22 seq
> crw-rw---T 1 root audio 116, 33 Jun 17 13:22 timer
> AplayDevices: Error: [Errno 2] No such file or directory
> ApportVersion: 2.0.1-0ubuntu8
> Architecture: amd64
> ArecordDevices: Error: [Errno 2] No such file or directory
> AudioDevicesInUse: Error: command ['fuser', '-v', '/dev/snd/seq',
> '/dev/snd/timer'] failed with exit code 1:
> CRDA: Error: [Errno 2] No such file or directory
> DistroRelease: Ubuntu 12.04
> HibernationDevice: RESUME=UUID=6bdcd41e-069d-48e1-831d-5789badf4aab
> InstallationMedia: Ubuntu-Server 12.04 LTS "Precise Pangolin" -
> Release
> amd64 (20120424.1)
> Lsusb:
> Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
> Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
> Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate
> Matching
> Hub
> Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate
> Matching
> Hub
> Bus 001 Device 003: ID 0557:2221 ATEN International Co., Ltd
> MachineType: Supermicro X9SCL/X9SCM
> Package: linux (not installed)
> PciMultimedia:
>
> ProcEnviron:
> TERM=xterm
> LANG=en_US.UTF-8
> SHELL=/bin/bash
> ProcFB: 0 EFI VGA
> ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-3.2.0-25-generic
> root=UUID=49e8b23b-7eb0-41ac-8343-d6586659c879 ro
> ProcVersionSignature: Ubuntu 3.2.0-25.40-generic 3.2.18
> RelatedPackageVersions:
> linux-restricted-modules-3.2.0-25-generic N/A
> linux-backports-modules-3.2.0-25-generic N/A
> linux-firmware 1.79
> RfKill: Error: [Errno 2] No such file or directory
> Tags: precise
> Uname: Linux 3.2.0-25-generic x86_64
> UpgradeStatus: No upgrade log present (probably fresh install)
> UserGroups:
>
> dmi.bios.date: 05/08/2012
> dmi.bios.vendor: American Megatrends Inc.
> dmi.bios.version: 2.00
> dmi.board.asset.tag: To be filled by O.E.M.
> dmi.board.name: X9SCL/X9SCM
> dmi.board.vendor: Supermicro
> dmi.board.version: 0123456789
> dmi.chassis.asset.tag: To Be Filled By O.E.M.
> dmi.chassis.type: 3
> dmi.chassis.vendor: Supermicro
> dmi.chassis.version: 0123456789
> dmi.modalias:
> dmi:bvnAmericanMegatrendsInc.:bvr2.00:bd05/08/2012:svnSupermicro:pnX9S
> CL/X9SCM:pvr0123456789:rvnSupermicro:rnX9SCL/X9SCM:rvr0123456789:cvnSu
> permicro:ct3:cvr0123456789:
> dmi.product.name: X9SCL/X9SCM
> dmi.product.version: 0123456789
> dmi.sys.vendor: Supermicro
>
> Detailed hardware information and ticket on ubuntu
> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1014490
>
> ---
> Denys Fedoryshchenko, Network Engineer, Virtual ISP S.A.L.
I'm looking into this now.
Thanks,
Bruce.
^ permalink raw reply
* Re: [RFC net-next (v2) 14/14] ixgbevf: set maximal number of default RSS queues
From: Alexander Duyck @ 2012-06-25 16:33 UTC (permalink / raw)
To: eilong; +Cc: Yuval Mintz, davem, netdev, Jeff Kirsher, Greg Rose
In-Reply-To: <1340639591.2486.25.camel@lb-tlvb-eilong.il.broadcom.com>
On 06/25/2012 08:53 AM, Eilon Greenstein wrote:
> On Mon, 2012-06-25 at 08:45 -0700, Alexander Duyck wrote:
>> On 06/25/2012 04:45 AM, Yuval Mintz wrote:
>>> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
>>> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
>>>
>>> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>>> Cc: Alexander Duyck <alexander.h.duyck@intel.com>
>>> Cc: Greg Rose <gregory.v.rose@intel.com>
>>> ---
>>> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 +-
>>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
>>> index f69ec42..7889644 100644
>>> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
>>> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
>>> @@ -2023,7 +2023,7 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
>>> * (roughly) twice the number of vectors as there are CPU's.
>>> */
>>> v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
>>> - (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
>>> + netif_get_num_default_rss_queues() * 2) + NON_Q_VECTORS;
>>>
>>> /* A failure in MSI-X entry allocation isn't fatal, but it does
>>> * mean we disable MSI-X capabilities of the adapter. */
>> I'm not even sure why you are bothering to alter this driver since it is
>> currently single queue only.
> Alex,
>
> Can you please explain the logic behind these lines in the current
> implementation?
> v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
> (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
> It looks as if you were trying to be generic and support a future in
> which this driver will support more than a single queue - to be future
> ready, this RFC is replacing the usage of num_online_cpus with
> netif_get_num_default_rss_queues. Are you suggesting to remove these
> lines all together? Keeping this minimum function with only the
> num_online_cpus does not seem right without considering also the new
> default value.
>
> Thanks,
> Eilon
Eilon,
It seems like you didn't listen to anything I told you for the last
round of patches.
You are confusing interrupt vectors with queues as you did with ixgbe.
The VF driver supports up to 3 interrupts, but is only single queue. As
such we can split things out so that we either support one vector with
both Tx and Rx or separate Tx and Rx vectors. How many vectors you have
doesn't really matter anyway since this patch doesn't limit queues. All
it does is limit the number of interrupt vectors.
I suggest you locate where we set "adapter->num_rx_queues" and attempt
to address the issue there.
Thanks,
Alex
^ permalink raw reply
* Re: 3.4-rc: NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out
From: Tomas Papan @ 2012-06-25 16:13 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <CAMGsXDRAE5RZduZnTRa-JmA9_N0Kv+juzYNB_0hf-x+Q8nkpSg@mail.gmail.com>
Hi,
The problem still exists in 3.4.4. I'm currently using 3.2.21, which is fine.
Unfortunately it is service affecting, after some time the machine
just froze. I'm using headless setup, so I can not tell if this causes
the problem (logs are empty). But I had with 3.2.x more than 30+ days
uptime and no problems or warnings whatsoever (dmesg and logs are
clear). I do not believe that I'm the only one with this problem,
r8169 is quite popular.
Is there anything what can I provide or try? I do not want to be stuck
on 3.2.x kernel.
[13513.912323] WARNING: at net/sched/sch_generic.c:256
dev_watchdog+0x16b/0x20f()
[13513.912327] Hardware name: SH55J
[13513.912330] NETDEV WATCHDOG: eth1 (r8169): transmit queue 0 timed out
[13513.912333] Modules linked in: vhost_net cls_route cls_u32 cls_fw
sch_sfq sch_htb ipt_REDIRECT ipt_MASQUERADE ipt_REJECT xt_limit
xt_tcpudp nf_conntrack_ipv6 nf_defrag_ipv6 xt_state iptable_nat nf_nat
nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 ip6table_filter
ip6_tables iptable_filter ip_tables x_tables kvm_intel kvm fuse r8169
[13513.912369] Pid: 0, comm: swapper/2 Not tainted 3.4.4 #1
[13513.912372] Call Trace:
[13513.912374] <IRQ> [<ffffffff81026881>] ? warn_slowpath_common+0x78/0x8c
[13513.912386] [<ffffffff81026936>] ? warn_slowpath_fmt+0x45/0x4a
[13513.912392] [<ffffffff81042fc2>] ? scheduler_tick+0xaf/0xc3
[13513.912400] [<ffffffff81049f70>] ? ktime_get+0x5f/0xb9
[13513.912404] [<ffffffff812535f0>] ? dev_watchdog+0x16b/0x20f
[13513.912411] [<ffffffff8102f3ae>] ? run_timer_softirq+0x177/0x209
[13513.912417] [<ffffffff8103e7b3>] ? hrtimer_interrupt+0x100/0x19b
[13513.912421] [<ffffffff81253485>] ? qdisc_reset+0x35/0x35
[13513.912428] [<ffffffff8102b256>] ? __do_softirq+0x7f/0x106
[13513.912434] [<ffffffff812e2a4c>] ? call_softirq+0x1c/0x30
[13513.912439] [<ffffffff81003376>] ? do_softirq+0x31/0x67
[13513.912444] [<ffffffff8102b503>] ? irq_exit+0x44/0x75
[13513.912448] [<ffffffff810032b5>] ? do_IRQ+0x94/0xad
[13513.912454] [<ffffffff812e1167>] ? common_interrupt+0x67/0x67
[13513.912457] <EOI> [<ffffffff81163f87>] ? intel_idle+0xde/0x103
[13513.912468] [<ffffffff81163f63>] ? intel_idle+0xba/0x103
[13513.912475] [<ffffffff81220c4a>] ? cpuidle_idle_call+0x7e/0xc4
[13513.912483] [<ffffffff81008e92>] ? cpu_idle+0x53/0x7c
[13513.912487] ---[ end trace 635a32207d8c1b48 ]---
[13513.915428] r8169 0000:01:00.0: eth1: link up
Thanks in advance
Tomas
On Tue, Jun 12, 2012 at 4:34 PM, Tomas Papan <tomas.papan@gmail.com> wrote:
> Hi Francois,
>
> Unfortunately after the warning occurred once again after 28 000 seconds.
> Is there anything else what can I do?
>
> Regards
> Tomas
>
> [28914.344765] ------------[ cut here ]------------
> [28914.344775] WARNING: at net/sched/sch_generic.c:256
> dev_watchdog+0x16b/0x20f()
> [28914.344779] Hardware name: SH55J
> [28914.344782] NETDEV WATCHDOG: eth1 (r8169): transmit queue 0 timed out
> [28914.344785] Modules linked in: vhost_net cls_route cls_u32 cls_fw
> sch_sfq sch_htb ipt_REDIRECT ipt_MASQUERADE xt_limit xt_tcpudp
> nf_conntrack_ipv6 nf_defrag_ipv6 xt_state iptable_nat nf_nat
> nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 ip6table_filter
> ip6_tables iptable_filter ip_tables x_tables kvm_intel kvm fuse r8169
> [28914.344819] Pid: 0, comm: swapper/2 Not tainted 3.4.2 #1
> [28914.344822] Call Trace:
> [28914.344825] <IRQ> [<ffffffff81026881>] ? warn_slowpath_common+0x78/0x8c
> [28914.344837] [<ffffffff81026936>] ? warn_slowpath_fmt+0x45/0x4a
> [28914.344843] [<ffffffff81042fc2>] ? scheduler_tick+0xaf/0xc3
> [28914.344850] [<ffffffff81049f70>] ? ktime_get+0x5f/0xb9
> [28914.344855] [<ffffffff812535a0>] ? dev_watchdog+0x16b/0x20f
> [28914.344861] [<ffffffff8102f3ae>] ? run_timer_softirq+0x177/0x209
> [28914.344868] [<ffffffff8103e7b3>] ? hrtimer_interrupt+0x100/0x19b
> [28914.344872] [<ffffffff81253435>] ? qdisc_reset+0x35/0x35
> [28914.344879] [<ffffffff8102b256>] ? __do_softirq+0x7f/0x106
> [28914.344884] [<ffffffff812e298c>] ? call_softirq+0x1c/0x30
> [28914.344890] [<ffffffff81003376>] ? do_softirq+0x31/0x67
> [28914.344895] [<ffffffff8102b503>] ? irq_exit+0x44/0x75
> [28914.344899] [<ffffffff810032b5>] ? do_IRQ+0x94/0xad
> [28914.344905] [<ffffffff812e10a7>] ? common_interrupt+0x67/0x67
> [28914.344908] <EOI> [<ffffffff81163f07>] ? intel_idle+0xde/0x103
> [28914.344919] [<ffffffff81163ee3>] ? intel_idle+0xba/0x103
> [28914.344926] [<ffffffff81220bfa>] ? cpuidle_idle_call+0x7e/0xc4
> [28914.344933] [<ffffffff81008e92>] ? cpu_idle+0x53/0x7c
> [28914.344937] ---[ end trace 3d8459064a9171b4 ]---
> [28914.347829] r8169 0000:01:00.0: eth1: link up
^ permalink raw reply
* [PATCH] net: nfc: fix panic in accept()
From: Eric Dumazet @ 2012-06-25 15:53 UTC (permalink / raw)
To: Sasha Levin
Cc: Dave Jones, Samuel Ortiz, David Miller, lauro.venancio,
aloisio.almeida, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless
In-Reply-To: <CA+1xoqcwr-5dzHvqkt9x0-xj9EFAywVfva=asbHXvX-LSBWqdA@mail.gmail.com>
From: Eric Dumazet <edumazet@google.com>
Sasha Levin reported following panic :
[ 2136.383310] BUG: unable to handle kernel NULL pointer dereference at
00000000000003b0
[ 2136.384022] IP: [<ffffffff8114e400>] __lock_acquire+0xc0/0x4b0
[ 2136.384022] PGD 131c4067 PUD 11c0c067 PMD 0
[ 2136.388106] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 2136.388106] CPU 1
[ 2136.388106] Pid: 24855, comm: trinity-child1 Tainted: G W
3.5.0-rc2-sasha-00015-g7b268f7 #374
[ 2136.388106] RIP: 0010:[<ffffffff8114e400>] [<ffffffff8114e400>]
__lock_acquire+0xc0/0x4b0
[ 2136.388106] RSP: 0018:ffff8800130b3ca8 EFLAGS: 00010046
[ 2136.388106] RAX: 0000000000000086 RBX: ffff88001186b000 RCX:
0000000000000000
[ 2136.388106] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
0000000000000000
[ 2136.388106] RBP: ffff8800130b3d08 R08: 0000000000000001 R09:
0000000000000000
[ 2136.388106] R10: 0000000000000000 R11: 0000000000000001 R12:
0000000000000002
[ 2136.388106] R13: 00000000000003b0 R14: 0000000000000000 R15:
0000000000000000
[ 2136.388106] FS: 00007fa5b1bd4700(0000) GS:ffff88001b800000(0000)
knlGS:0000000000000000
[ 2136.388106] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2136.388106] CR2: 00000000000003b0 CR3: 0000000011d1f000 CR4:
00000000000406e0
[ 2136.388106] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 2136.388106] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
0000000000000400
[ 2136.388106] Process trinity-child1 (pid: 24855, threadinfo
ffff8800130b2000, task ffff88001186b000)
[ 2136.388106] Stack:
[ 2136.388106] ffff8800130b3cd8 ffffffff81121785 ffffffff81236774
000080d000000001
[ 2136.388106] ffff88001b9d6c00 00000000001d6c00 ffffffff130b3d08
ffff88001186b000
[ 2136.388106] 0000000000000000 0000000000000002 0000000000000000
0000000000000000
[ 2136.388106] Call Trace:
[ 2136.388106] [<ffffffff81121785>] ? sched_clock_local+0x25/0x90
[ 2136.388106] [<ffffffff81236774>] ? get_empty_filp+0x74/0x220
[ 2136.388106] [<ffffffff8114e97a>] lock_acquire+0x18a/0x1e0
[ 2136.388106] [<ffffffff836b37df>] ? rawsock_release+0x4f/0xa0
[ 2136.388106] [<ffffffff837c0ef0>] _raw_write_lock_bh+0x40/0x80
[ 2136.388106] [<ffffffff836b37df>] ? rawsock_release+0x4f/0xa0
[ 2136.388106] [<ffffffff836b37df>] rawsock_release+0x4f/0xa0
[ 2136.388106] [<ffffffff8321cfe8>] sock_release+0x18/0x70
[ 2136.388106] [<ffffffff8321d069>] sock_close+0x29/0x30
[ 2136.388106] [<ffffffff81236bca>] __fput+0x11a/0x2c0
[ 2136.388106] [<ffffffff81236d85>] fput+0x15/0x20
[ 2136.388106] [<ffffffff8321de34>] sys_accept4+0x1b4/0x200
[ 2136.388106] [<ffffffff837c165c>] ? _raw_spin_unlock_irq+0x4c/0x80
[ 2136.388106] [<ffffffff837c1669>] ? _raw_spin_unlock_irq+0x59/0x80
[ 2136.388106] [<ffffffff837c2565>] ? sysret_check+0x22/0x5d
[ 2136.388106] [<ffffffff8321de8b>] sys_accept+0xb/0x10
[ 2136.388106] [<ffffffff837c2539>] system_call_fastpath+0x16/0x1b
[ 2136.388106] Code: ec 04 00 0f 85 ea 03 00 00 be d5 0b 00 00 48 c7 c7
8a c1 40 84 e8 b1 a5 f8 ff 31 c0 e9 d4 03 00 00 66 2e 0f 1f 84 00 00 00
00 00 <49> 81 7d 00 60 73 5e 85 b8 01 00 00 00 44 0f 44 e0 83 fe 01 77
[ 2136.388106] RIP [<ffffffff8114e400>] __lock_acquire+0xc0/0x4b0
[ 2136.388106] RSP <ffff8800130b3ca8>
[ 2136.388106] CR2: 00000000000003b0
[ 2136.388106] ---[ end trace 6d450e935ee18982 ]---
[ 2136.388106] Kernel panic - not syncing: Fatal exception in interrupt
rawsock_release() should test if sock->sk is NULL before calling
sock_orphan()/sock_put()
Reported-by: Sasha Levin <levinsasha928@gmail.com>
Tested-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
---
net/nfc/rawsock.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index ec1134c..208416e 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -54,11 +54,12 @@ static int rawsock_release(struct socket *sock)
{
struct sock *sk = sock->sk;
- pr_debug("sock=%p\n", sock);
-
- sock_orphan(sk);
- sock_put(sk);
+ pr_debug("sock=%p sk=%p\n", sock, sk);
+ if (sk) {
+ sock_orphan(sk);
+ sock_put(sk);
+ }
return 0;
}
^ permalink raw reply related
* Re: [RFC net-next (v2) 14/14] ixgbevf: set maximal number of default RSS queues
From: Eilon Greenstein @ 2012-06-25 15:53 UTC (permalink / raw)
To: Alexander Duyck; +Cc: Yuval Mintz, davem, netdev, Jeff Kirsher, Greg Rose
In-Reply-To: <4FE88794.9090704@intel.com>
On Mon, 2012-06-25 at 08:45 -0700, Alexander Duyck wrote:
> On 06/25/2012 04:45 AM, Yuval Mintz wrote:
> > Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
> > Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
> >
> > Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > Cc: Alexander Duyck <alexander.h.duyck@intel.com>
> > Cc: Greg Rose <gregory.v.rose@intel.com>
> > ---
> > drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > index f69ec42..7889644 100644
> > --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > @@ -2023,7 +2023,7 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
> > * (roughly) twice the number of vectors as there are CPU's.
> > */
> > v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
> > - (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
> > + netif_get_num_default_rss_queues() * 2) + NON_Q_VECTORS;
> >
> > /* A failure in MSI-X entry allocation isn't fatal, but it does
> > * mean we disable MSI-X capabilities of the adapter. */
> I'm not even sure why you are bothering to alter this driver since it is
> currently single queue only.
Alex,
Can you please explain the logic behind these lines in the current
implementation?
v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
(int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
It looks as if you were trying to be generic and support a future in
which this driver will support more than a single queue - to be future
ready, this RFC is replacing the usage of num_online_cpus with
netif_get_num_default_rss_queues. Are you suggesting to remove these
lines all together? Keeping this minimum function with only the
num_online_cpus does not seem right without considering also the new
default value.
Thanks,
Eilon
^ permalink raw reply
* Re: [RFC net-next (v2) 14/14] ixgbevf: set maximal number of default RSS queues
From: Alexander Duyck @ 2012-06-25 15:45 UTC (permalink / raw)
To: Yuval Mintz; +Cc: davem, netdev, eilong, Jeff Kirsher, Greg Rose
In-Reply-To: <1340624745-8650-15-git-send-email-yuvalmin@broadcom.com>
On 06/25/2012 04:45 AM, Yuval Mintz wrote:
> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
>
> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Cc: Alexander Duyck <alexander.h.duyck@intel.com>
> Cc: Greg Rose <gregory.v.rose@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> index f69ec42..7889644 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> @@ -2023,7 +2023,7 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
> * (roughly) twice the number of vectors as there are CPU's.
> */
> v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
> - (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
> + netif_get_num_default_rss_queues() * 2) + NON_Q_VECTORS;
>
> /* A failure in MSI-X entry allocation isn't fatal, but it does
> * mean we disable MSI-X capabilities of the adapter. */
I'm not even sure why you are bothering to alter this driver since it is
currently single queue only.
Thanks,
Alex
^ permalink raw reply
* Re: [RFC net-next (v2) 12/14] ixgbe: set maximal number of default RSS queues
From: Alexander Duyck @ 2012-06-25 15:44 UTC (permalink / raw)
To: Yuval Mintz; +Cc: davem, netdev, eilong, Jeff Kirsher, John Fastabend
In-Reply-To: <1340624745-8650-13-git-send-email-yuvalmin@broadcom.com>
On 06/25/2012 04:45 AM, Yuval Mintz wrote:
> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
>
> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Cc: John Fastabend <john.r.fastabend@intel.com>
> Cc: Alexander Duyck <alexander.h.duyck@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> index af1a531..b352ea8 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> @@ -802,7 +802,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
> * The default is to use pairs of vectors.
> */
> v_budget = max(adapter->num_rx_queues, adapter->num_tx_queues);
> - v_budget = min_t(int, v_budget, num_online_cpus());
> + v_budget = min_t(int, v_budget, netif_get_num_default_rss_queues());
> v_budget += NON_Q_VECTORS;
>
> /*
This doesn't limit queues, only interrupt vectors. As I told you before
you should look at the ixgbe_set_rss_queues function if you actually
want to limit the number of RSS queues.
Thanks,
Alex
^ permalink raw reply
* [PATCH] net: l2tp_eth: use LLTX to avoid LOCKDEP splats
From: Eric Dumazet @ 2012-06-25 15:35 UTC (permalink / raw)
To: Denys Fedoryshchenko, David Miller
Cc: netdev, Hong zhi guo, James Chapman, Francois Romieu
In-Reply-To: <7ed49f446365ac625437702d92946add@visp.net.lb>
From: Eric Dumazet <edumazet@google.com>
Denys Fedoryshchenko reported a LOCKDEP issue with l2tp code.
[ 8683.927442] ======================================================
[ 8683.927555] [ INFO: possible circular locking dependency detected ]
[ 8683.927672] 3.4.1-build-0061 #14 Not tainted
[ 8683.927782] -------------------------------------------------------
[ 8683.927895] swapper/0/0 is trying to acquire lock:
[ 8683.928007] (slock-AF_INET){+.-...}, at: [<e0fc73ec>]
l2tp_xmit_skb+0x173/0x47e [l2tp_core]
[ 8683.928121]
[ 8683.928121] but task is already holding lock:
[ 8683.928121] (_xmit_ETHER#2){+.-...}, at: [<c02f062d>]
sch_direct_xmit+0x36/0x119
[ 8683.928121]
[ 8683.928121] which lock already depends on the new lock.
[ 8683.928121]
[ 8683.928121]
[ 8683.928121] the existing dependency chain (in reverse order) is:
[ 8683.928121]
[ 8683.928121] -> #1 (_xmit_ETHER#2){+.-...}:
[ 8683.928121] [<c015a561>] lock_acquire+0x71/0x85
[ 8683.928121] [<c034da2d>] _raw_spin_lock+0x33/0x40
[ 8683.928121] [<c0304e0c>] ip_send_reply+0xf2/0x1ce
[ 8683.928121] [<c0317dbc>] tcp_v4_send_reset+0x153/0x16f
[ 8683.928121] [<c0317f4a>] tcp_v4_do_rcv+0x172/0x194
[ 8683.928121] [<c031929b>] tcp_v4_rcv+0x387/0x5a0
[ 8683.928121] [<c03001d0>] ip_local_deliver_finish+0x13a/0x1e9
[ 8683.928121] [<c0300645>] NF_HOOK.clone.11+0x46/0x4d
[ 8683.928121] [<c030075b>] ip_local_deliver+0x41/0x45
[ 8683.928121] [<c03005dd>] ip_rcv_finish+0x31a/0x33c
[ 8683.928121] [<c0300645>] NF_HOOK.clone.11+0x46/0x4d
[ 8683.928121] [<c0300960>] ip_rcv+0x201/0x23d
[ 8683.928121] [<c02de91b>] __netif_receive_skb+0x329/0x378
[ 8683.928121] [<c02deae8>] netif_receive_skb+0x4e/0x7d
[ 8683.928121] [<e08d5ef3>] rtl8139_poll+0x243/0x33d [8139too]
[ 8683.928121] [<c02df103>] net_rx_action+0x90/0x15d
[ 8683.928121] [<c012b2b5>] __do_softirq+0x7b/0x118
[ 8683.928121]
[ 8683.928121] -> #0 (slock-AF_INET){+.-...}:
[ 8683.928121] [<c0159f1b>] __lock_acquire+0x9a3/0xc27
[ 8683.928121] [<c015a561>] lock_acquire+0x71/0x85
[ 8683.928121] [<c034da2d>] _raw_spin_lock+0x33/0x40
[ 8683.928121] [<e0fc73ec>] l2tp_xmit_skb+0x173/0x47e
[l2tp_core]
[ 8683.928121] [<e0fe31fb>] l2tp_eth_dev_xmit+0x1a/0x2f
[l2tp_eth]
[ 8683.928121] [<c02e01e7>] dev_hard_start_xmit+0x333/0x3f2
[ 8683.928121] [<c02f064c>] sch_direct_xmit+0x55/0x119
[ 8683.928121] [<c02e0528>] dev_queue_xmit+0x282/0x418
[ 8683.928121] [<c031f4fb>] NF_HOOK.clone.19+0x45/0x4c
[ 8683.928121] [<c031f524>] arp_xmit+0x22/0x24
[ 8683.928121] [<c031f567>] arp_send+0x41/0x48
[ 8683.928121] [<c031fa7d>] arp_process+0x289/0x491
[ 8683.928121] [<c031f4fb>] NF_HOOK.clone.19+0x45/0x4c
[ 8683.928121] [<c031f7a0>] arp_rcv+0xb1/0xc3
[ 8683.928121] [<c02de91b>] __netif_receive_skb+0x329/0x378
[ 8683.928121] [<c02de9d3>] process_backlog+0x69/0x130
[ 8683.928121] [<c02df103>] net_rx_action+0x90/0x15d
[ 8683.928121] [<c012b2b5>] __do_softirq+0x7b/0x118
[ 8683.928121]
[ 8683.928121] other info that might help us debug this:
[ 8683.928121]
[ 8683.928121] Possible unsafe locking scenario:
[ 8683.928121]
[ 8683.928121] CPU0 CPU1
[ 8683.928121] ---- ----
[ 8683.928121] lock(_xmit_ETHER#2);
[ 8683.928121] lock(slock-AF_INET);
[ 8683.928121] lock(_xmit_ETHER#2);
[ 8683.928121] lock(slock-AF_INET);
[ 8683.928121]
[ 8683.928121] *** DEADLOCK ***
[ 8683.928121]
[ 8683.928121] 3 locks held by swapper/0/0:
[ 8683.928121] #0: (rcu_read_lock){.+.+..}, at: [<c02dbc10>]
rcu_lock_acquire+0x0/0x30
[ 8683.928121] #1: (rcu_read_lock_bh){.+....}, at: [<c02dbc10>]
rcu_lock_acquire+0x0/0x30
[ 8683.928121] #2: (_xmit_ETHER#2){+.-...}, at: [<c02f062d>]
sch_direct_xmit+0x36/0x119
[ 8683.928121]
[ 8683.928121] stack backtrace:
[ 8683.928121] Pid: 0, comm: swapper/0 Not tainted 3.4.1-build-0061 #14
[ 8683.928121] Call Trace:
[ 8683.928121] [<c034bdd2>] ? printk+0x18/0x1a
[ 8683.928121] [<c0158904>] print_circular_bug+0x1ac/0x1b6
[ 8683.928121] [<c0159f1b>] __lock_acquire+0x9a3/0xc27
[ 8683.928121] [<c015a561>] lock_acquire+0x71/0x85
[ 8683.928121] [<e0fc73ec>] ? l2tp_xmit_skb+0x173/0x47e [l2tp_core]
[ 8683.928121] [<c034da2d>] _raw_spin_lock+0x33/0x40
[ 8683.928121] [<e0fc73ec>] ? l2tp_xmit_skb+0x173/0x47e [l2tp_core]
[ 8683.928121] [<e0fc73ec>] l2tp_xmit_skb+0x173/0x47e [l2tp_core]
[ 8683.928121] [<e0fe31fb>] l2tp_eth_dev_xmit+0x1a/0x2f [l2tp_eth]
[ 8683.928121] [<c02e01e7>] dev_hard_start_xmit+0x333/0x3f2
[ 8683.928121] [<c02f064c>] sch_direct_xmit+0x55/0x119
[ 8683.928121] [<c02e0528>] dev_queue_xmit+0x282/0x418
[ 8683.928121] [<c02e02a6>] ? dev_hard_start_xmit+0x3f2/0x3f2
[ 8683.928121] [<c031f4fb>] NF_HOOK.clone.19+0x45/0x4c
[ 8683.928121] [<c031f524>] arp_xmit+0x22/0x24
[ 8683.928121] [<c02e02a6>] ? dev_hard_start_xmit+0x3f2/0x3f2
[ 8683.928121] [<c031f567>] arp_send+0x41/0x48
[ 8683.928121] [<c031fa7d>] arp_process+0x289/0x491
[ 8683.928121] [<c031f7f4>] ? __neigh_lookup.clone.20+0x42/0x42
[ 8683.928121] [<c031f4fb>] NF_HOOK.clone.19+0x45/0x4c
[ 8683.928121] [<c031f7a0>] arp_rcv+0xb1/0xc3
[ 8683.928121] [<c031f7f4>] ? __neigh_lookup.clone.20+0x42/0x42
[ 8683.928121] [<c02de91b>] __netif_receive_skb+0x329/0x378
[ 8683.928121] [<c02de9d3>] process_backlog+0x69/0x130
[ 8683.928121] [<c02df103>] net_rx_action+0x90/0x15d
[ 8683.928121] [<c012b2b5>] __do_softirq+0x7b/0x118
[ 8683.928121] [<c012b23a>] ? local_bh_enable+0xd/0xd
[ 8683.928121] <IRQ> [<c012b4d0>] ? irq_exit+0x41/0x91
[ 8683.928121] [<c0103c6f>] ? do_IRQ+0x79/0x8d
[ 8683.928121] [<c0157ea1>] ? trace_hardirqs_off_caller+0x2e/0x86
[ 8683.928121] [<c034ef6e>] ? common_interrupt+0x2e/0x34
[ 8683.928121] [<c0108a33>] ? default_idle+0x23/0x38
[ 8683.928121] [<c01091a8>] ? cpu_idle+0x55/0x6f
[ 8683.928121] [<c033df25>] ? rest_init+0xa1/0xa7
[ 8683.928121] [<c033de84>] ? __read_lock_failed+0x14/0x14
[ 8683.928121] [<c0498745>] ? start_kernel+0x303/0x30a
[ 8683.928121] [<c0498209>] ? repair_env_string+0x51/0x51
[ 8683.928121] [<c04980a8>] ? i386_start_kernel+0xa8/0xaf
It appears that like most virtual devices, l2tp should be converted to
LLTX mode.
This patch takes care of statistics using atomic_long in both RX and TX
paths, and fix a bug in l2tp_eth_dev_recv(), which was caching skb->data
before a pskb_may_pull() call.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
Cc: James Chapman <jchapman@katalix.com>
Cc: Hong zhi guo <honkiko@gmail.com>
Cc: Francois Romieu <romieu@fr.zoreil.com>
---
Should be applied after "net: l2tp_eth: fix l2tp_eth_dev_xmit race"
net/l2tp/l2tp_eth.c | 43 +++++++++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index c3738f4..47b259f 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -42,6 +42,11 @@ struct l2tp_eth {
struct sock *tunnel_sock;
struct l2tp_session *session;
struct list_head list;
+ atomic_long_t tx_bytes;
+ atomic_long_t tx_packets;
+ atomic_long_t rx_bytes;
+ atomic_long_t rx_packets;
+ atomic_long_t rx_errors;
};
/* via l2tp_session_priv() */
@@ -88,24 +93,40 @@ static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev)
struct l2tp_eth *priv = netdev_priv(dev);
struct l2tp_session *session = priv->session;
- dev->stats.tx_bytes += skb->len;
- dev->stats.tx_packets++;
+ atomic_long_add(skb->len, &priv->tx_bytes);
+ atomic_long_inc(&priv->tx_packets);
l2tp_xmit_skb(session, skb, session->hdr_len);
return NETDEV_TX_OK;
}
+static struct rtnl_link_stats64 *l2tp_eth_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *stats)
+{
+ struct l2tp_eth *priv = netdev_priv(dev);
+
+ stats->tx_bytes = atomic_long_read(&priv->tx_bytes);
+ stats->tx_packets = atomic_long_read(&priv->tx_packets);
+ stats->rx_bytes = atomic_long_read(&priv->rx_bytes);
+ stats->rx_packets = atomic_long_read(&priv->rx_packets);
+ stats->rx_errors = atomic_long_read(&priv->rx_errors);
+ return stats;
+}
+
+
static struct net_device_ops l2tp_eth_netdev_ops = {
.ndo_init = l2tp_eth_dev_init,
.ndo_uninit = l2tp_eth_dev_uninit,
.ndo_start_xmit = l2tp_eth_dev_xmit,
+ .ndo_get_stats64 = l2tp_eth_get_stats64,
};
static void l2tp_eth_dev_setup(struct net_device *dev)
{
ether_setup(dev);
- dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->features |= NETIF_F_LLTX;
dev->netdev_ops = &l2tp_eth_netdev_ops;
dev->destructor = free_netdev;
}
@@ -114,17 +135,17 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
{
struct l2tp_eth_sess *spriv = l2tp_session_priv(session);
struct net_device *dev = spriv->dev;
+ struct l2tp_eth *priv = netdev_priv(dev);
if (session->debug & L2TP_MSG_DATA) {
unsigned int length;
- u8 *ptr = skb->data;
length = min(32u, skb->len);
if (!pskb_may_pull(skb, length))
goto error;
pr_debug("%s: eth recv\n", session->name);
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length);
}
if (!pskb_may_pull(skb, sizeof(ETH_HLEN)))
@@ -139,15 +160,15 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
nf_reset(skb);
if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) {
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += data_len;
- } else
- dev->stats.rx_errors++;
-
+ atomic_long_inc(&priv->rx_packets);
+ atomic_long_add(data_len, &priv->rx_bytes);
+ } else {
+ atomic_long_inc(&priv->rx_errors);
+ }
return;
error:
- dev->stats.rx_errors++;
+ atomic_long_inc(&priv->rx_errors);
kfree_skb(skb);
}
^ permalink raw reply related
* Re: [PATCH] mac80211: fix build warning
From: Alexandre Pereira da Silva @ 2012-06-25 15:33 UTC (permalink / raw)
To: Mohammed Shafi
Cc: John W. Linville, Johannes Berg, David S. Miller, linux-wireless,
netdev, linux-kernel
In-Reply-To: <CAD2nsn08gkYJnyYfqyZT8VX-bFPgDVZPgVSHE_QBEuXj5aEWMw@mail.gmail.com>
On Mon, Jun 25, 2012 at 12:31 PM, Mohammed Shafi
<shafi.wireless@gmail.com> wrote:
> Hi,
>
> On Mon, Jun 25, 2012 at 8:49 PM, Alexandre Pereira da Silva
> <aletes.xgr@gmail.com> wrote:
>> Fix:
>> net/mac80211/mlme.c: In function 'ieee80211_prep_connection':
>> net/mac80211/mlme.c:3035:19: warning: 'sta' may be used uninitialized in
>> this function
>>
>> Initialize sta to NULL
>
> i think already fixed by and there in wireless-testing
> http://www.spinics.net/lists/linux-wireless/msg92385.html
Ok, thanks for pointing that out.
^ permalink raw reply
* Re: [PATCH] mac80211: fix build warning
From: Mohammed Shafi @ 2012-06-25 15:31 UTC (permalink / raw)
To: Alexandre Pereira da Silva
Cc: John W. Linville, Johannes Berg, David S. Miller, linux-wireless,
netdev, linux-kernel
In-Reply-To: <1340637550-12669-1-git-send-email-aletes.xgr@gmail.com>
Hi,
On Mon, Jun 25, 2012 at 8:49 PM, Alexandre Pereira da Silva
<aletes.xgr@gmail.com> wrote:
> Fix:
> net/mac80211/mlme.c: In function 'ieee80211_prep_connection':
> net/mac80211/mlme.c:3035:19: warning: 'sta' may be used uninitialized in
> this function
>
> Initialize sta to NULL
i think already fixed by and there in wireless-testing
http://www.spinics.net/lists/linux-wireless/msg92385.html
>
> Signed-off-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
> ---
> net/mac80211/mlme.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> index 91d84cc..cfe6b43 100644
> --- a/net/mac80211/mlme.c
> +++ b/net/mac80211/mlme.c
> @@ -3032,7 +3032,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
> struct ieee80211_local *local = sdata->local;
> struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
> struct ieee80211_bss *bss = (void *)cbss->priv;
> - struct sta_info *sta;
> + struct sta_info *sta = NULL;
> bool have_sta = false;
> int err;
> int ht_cfreq;
> --
> 1.7.10
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
thanks,
shafi
^ permalink raw reply
* [PATCH] mac80211: fix build warning
From: Alexandre Pereira da Silva @ 2012-06-25 15:19 UTC (permalink / raw)
Cc: Alexandre Pereira da Silva, John W. Linville, Johannes Berg,
David S. Miller, linux-wireless, netdev, linux-kernel
Fix:
net/mac80211/mlme.c: In function 'ieee80211_prep_connection':
net/mac80211/mlme.c:3035:19: warning: 'sta' may be used uninitialized in
this function
Initialize sta to NULL
Signed-off-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
---
net/mac80211/mlme.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 91d84cc..cfe6b43 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3032,7 +3032,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_bss *bss = (void *)cbss->priv;
- struct sta_info *sta;
+ struct sta_info *sta = NULL;
bool have_sta = false;
int err;
int ht_cfreq;
--
1.7.10
^ permalink raw reply related
* Fw: [Bug 43671] New: 1282:9102 Davicom DM9102 issue
From: Stephen Hemminger @ 2012-06-25 15:15 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Sat, 23 Jun 2012 05:16:31 +0000 (UTC)
From: bugzilla-daemon@bugzilla.kernel.org
To: shemminger@linux-foundation.org
Subject: [Bug 43671] New: 1282:9102 Davicom DM9102 issue
https://bugzilla.kernel.org/show_bug.cgi?id=43671
Summary: 1282:9102 Davicom DM9102 issue
Product: Networking
Version: 2.5
Kernel Version: Linux version 3.5.0-999-generic (apw@gomeisa) (gcc
version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) )
#201206090407 SMP Sat Jun 9 08:14:58 UTC 2012
Platform: All
OS/Version: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
AssignedTo: shemminger@linux-foundation.org
ReportedBy: p.satishchandra@gmail.com
Regression: No
Created an attachment (id=74001)
--> (https://bugzilla.kernel.org/attachment.cgi?id=74001)
cpuinfo, dmesg, iomem, ioports, lspci, modules, scsi
Ethernet cards of Davicom DM9102 do not work. Many people suggest trying with
'dmfe' module rather than 'tulip' but neither works. The syslog is full of
'eth0: Tx timeout - resetting' messages. The bug is also reported in Launchpad
(url - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/819868) but it was
suggested to report it to the mainline kernel.
--
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.
^ permalink raw reply
* Re: net: nfc: BUG and panic in accept() on 3.5-rc2
From: Sasha Levin @ 2012-06-25 15:04 UTC (permalink / raw)
To: Dave Jones, Sasha Levin, Samuel Ortiz, Eric Dumazet, David Miller,
lauro.venancio, aloisio.almeida, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless
In-Reply-To: <20120611172545.GA1776@redhat.com>
On Mon, Jun 11, 2012 at 7:25 PM, Dave Jones <davej@redhat.com> wrote:
> On Mon, Jun 11, 2012 at 06:56:50PM +0200, Sasha Levin wrote:
>
> > > > > > > What's trinity ?
> > > > > > > Also, if this one is reproducible, would you mind sharing some details about
> > > > > > > how we could reproduce it ?
> > > > > >
> > > > > > Well, bugfix should be trivial enough ;)
> > > > > Yep, I looked at the code only after looking at Sasha's report.
> > > > >
> > > > > Thanks for the patch, do you mind if I add your SOB to it ?
> > > >
> > > > I would prefer making sure it fixes the bug first ;)
> > > Sure, although your patch makes sense regardless of that :)
> > > I'll still wait for Sasha to confirm that it fixes his crash.
> >
> > I don't have a direct way of reproducing it, but I've put it in the test
> > vm and the fuzzer is running, I'll let you know tomorrow if it happened
> > again.
>
> You might be able to trigger it faster by using -P PF_NFC, which will
> force trinity to only use NFC sockets.
>
> sidenote: most protocols trigger the module to be auto-loaded when a socket
> is created. This doesn't seem to happen with nfc, making me need to manually
> modprobe it first. Intentional ?
It fixes the bug, wasn't been able to reproduce it since then.
^ permalink raw reply
* Re: [net-next RFC V4 PATCH 0/4] Multiqueue virtio-net
From: John Fastabend @ 2012-06-25 14:13 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: krkumar2, habanero, mashirle, kvm, netdev, linux-kernel,
virtualization, edumazet, tahm, jwhan, davem
In-Reply-To: <20120625100758.GB19169@redhat.com>
On 6/25/2012 3:07 AM, Michael S. Tsirkin wrote:
> On Mon, Jun 25, 2012 at 05:16:48PM +0800, Jason Wang wrote:
>> Hello All:
>>
>> This series is an update version of multiqueue virtio-net driver based on
>> Krishna Kumar's work to let virtio-net use multiple rx/tx queues to do the
>> packets reception and transmission. Please review and comments.
>>
>> Test Environment:
>> - Intel(R) Xeon(R) CPU E5620 @ 2.40GHz, 8 cores 2 numa nodes
>> - Two directed connected 82599
>>
>> Test Summary:
>>
>> - Highlights: huge improvements on TCP_RR test
>> - Lowlights: regression on small packet transmission, higher cpu utilization
>> than single queue, need further optimization
>
> Didn't review yet, reacting this this paragraph:
>
> To avoid regressions, it seems reasonable to make
> the device use a single queue by default for now.
> Add a way to switch multiqueue on/off using ethtool.
>
> This way guest admin can tune the device for the
> workload manually until we manage to imlement some
> self-tuning heuristics.
>
Ethtool already has this switch 'ethtool -L' can be
used to set the number tx/rx channels. So you would
likely just need to add a set_channels hook.
.John
^ permalink raw reply
* [PATCH v2 net-next v3 3/3] 6lowpan: remove excessive argument in pr_debug
From: Alexander Smirnov @ 2012-06-25 13:49 UTC (permalink / raw)
To: davem; +Cc: netdev, dbaryshkov, Alexander Smirnov
In-Reply-To: <1340632143-27794-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Remove excessive __func__ argument in pr_debug function and some
excessive debug messages.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
---
net/ieee802154/6lowpan.c | 94 ++++++++++++++++++----------------------------
1 files changed, 37 insertions(+), 57 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index b45e229..ad0c226 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -240,8 +240,7 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr,
lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr);
}
- pr_debug("(%s): uncompressing %d + %d => ", __func__, prefcount,
- postcount);
+ pr_debug("uncompressing %d + %d => ", prefcount, postcount);
lowpan_raw_dump_inline(NULL, NULL, ipaddr->s6_addr, 16);
return 0;
@@ -252,13 +251,11 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
{
struct udphdr *uh = udp_hdr(skb);
- pr_debug("(%s): UDP header compression\n", __func__);
-
if (((uh->source & LOWPAN_NHC_UDP_4BIT_MASK) ==
LOWPAN_NHC_UDP_4BIT_PORT) &&
((uh->dest & LOWPAN_NHC_UDP_4BIT_MASK) ==
LOWPAN_NHC_UDP_4BIT_PORT)) {
- pr_debug("(%s): both ports compression to 4 bits\n", __func__);
+ pr_debug("UDP header: both ports compression to 4 bits\n");
**hc06_ptr = LOWPAN_NHC_UDP_CS_P_11;
**(hc06_ptr + 1) = /* subtraction is faster */
(u8)((uh->dest - LOWPAN_NHC_UDP_4BIT_PORT) +
@@ -266,20 +263,20 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
*hc06_ptr += 2;
} else if ((uh->dest & LOWPAN_NHC_UDP_8BIT_MASK) ==
LOWPAN_NHC_UDP_8BIT_PORT) {
- pr_debug("(%s): remove 8 bits of dest\n", __func__);
+ pr_debug("UDP header: remove 8 bits of dest\n");
**hc06_ptr = LOWPAN_NHC_UDP_CS_P_01;
memcpy(*hc06_ptr + 1, &uh->source, 2);
**(hc06_ptr + 3) = (u8)(uh->dest - LOWPAN_NHC_UDP_8BIT_PORT);
*hc06_ptr += 4;
} else if ((uh->source & LOWPAN_NHC_UDP_8BIT_MASK) ==
LOWPAN_NHC_UDP_8BIT_PORT) {
- pr_debug("(%s): remove 8 bits of source\n", __func__);
+ pr_debug("UDP header: remove 8 bits of source\n");
**hc06_ptr = LOWPAN_NHC_UDP_CS_P_10;
memcpy(*hc06_ptr + 1, &uh->dest, 2);
**(hc06_ptr + 3) = (u8)(uh->source - LOWPAN_NHC_UDP_8BIT_PORT);
*hc06_ptr += 4;
} else {
- pr_debug("(%s): can't compress header\n", __func__);
+ pr_debug("UDP header: can't compress\n");
**hc06_ptr = LOWPAN_NHC_UDP_CS_P_00;
memcpy(*hc06_ptr + 1, &uh->source, 2);
memcpy(*hc06_ptr + 3, &uh->dest, 2);
@@ -323,7 +320,7 @@ lowpan_uncompress_udp_header(struct sk_buff *skb)
goto err;
if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
- pr_debug("(%s): UDP header uncompression\n", __func__);
+ pr_debug("UDP header uncompression\n");
switch (tmp & LOWPAN_NHC_UDP_CS_P_11) {
case LOWPAN_NHC_UDP_CS_P_00:
memcpy(&uh->source, &skb->data[0], 2);
@@ -349,19 +346,19 @@ lowpan_uncompress_udp_header(struct sk_buff *skb)
skb_pull(skb, 1);
break;
default:
- pr_debug("(%s) ERROR: unknown UDP format\n", __func__);
+ pr_debug("ERROR: unknown UDP format\n");
goto err;
break;
}
- pr_debug("(%s): uncompressed UDP ports: src = %d, dst = %d\n",
- __func__, uh->source, uh->dest);
+ pr_debug("uncompressed UDP ports: src = %d, dst = %d\n",
+ uh->source, uh->dest);
/* copy checksum */
memcpy(&uh->check, &skb->data[0], 2);
skb_pull(skb, 2);
} else {
- pr_debug("(%s): ERROR: unsupported NH format\n", __func__);
+ pr_debug("ERROR: unsupported NH format\n");
goto err;
}
@@ -394,10 +391,9 @@ static int lowpan_header_create(struct sk_buff *skb,
hdr = ipv6_hdr(skb);
hc06_ptr = head + 2;
- pr_debug("(%s): IPv6 header dump:\n\tversion = %d\n\tlength = %d\n"
- "\tnexthdr = 0x%02x\n\thop_lim = %d\n", __func__,
- hdr->version, ntohs(hdr->payload_len), hdr->nexthdr,
- hdr->hop_limit);
+ pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n"
+ "\tnexthdr = 0x%02x\n\thop_lim = %d\n", hdr->version,
+ ntohs(hdr->payload_len), hdr->nexthdr, hdr->hop_limit);
lowpan_raw_dump_table(__func__, "raw skb network header dump",
skb_network_header(skb), sizeof(struct ipv6hdr));
@@ -498,23 +494,22 @@ static int lowpan_header_create(struct sk_buff *skb,
/* source address compression */
if (is_addr_unspecified(&hdr->saddr)) {
- pr_debug("(%s): source address is unspecified, setting SAC\n",
- __func__);
+ pr_debug("source address is unspecified, setting SAC\n");
iphc1 |= LOWPAN_IPHC_SAC;
/* TODO: context lookup */
} else if (is_addr_link_local(&hdr->saddr)) {
- pr_debug("(%s): source address is link-local\n", __func__);
+ pr_debug("source address is link-local\n");
iphc1 |= lowpan_compress_addr_64(&hc06_ptr,
LOWPAN_IPHC_SAM_BIT, &hdr->saddr, saddr);
} else {
- pr_debug("(%s): send the full source address\n", __func__);
+ pr_debug("send the full source address\n");
memcpy(hc06_ptr, &hdr->saddr.s6_addr16[0], 16);
hc06_ptr += 16;
}
/* destination address compression */
if (is_addr_mcast(&hdr->daddr)) {
- pr_debug("(%s): destination address is multicast", __func__);
+ pr_debug("destination address is multicast: ");
iphc1 |= LOWPAN_IPHC_M;
if (lowpan_is_mcast_addr_compressable8(&hdr->daddr)) {
pr_debug("compressed to 1 octet\n");
@@ -543,14 +538,13 @@ static int lowpan_header_create(struct sk_buff *skb,
hc06_ptr += 16;
}
} else {
- pr_debug("(%s): destination address is unicast: ", __func__);
/* TODO: context lookup */
if (is_addr_link_local(&hdr->daddr)) {
- pr_debug("destination address is link-local\n");
+ pr_debug("dest address is unicast and link-local\n");
iphc1 |= lowpan_compress_addr_64(&hc06_ptr,
LOWPAN_IPHC_DAM_BIT, &hdr->daddr, daddr);
} else {
- pr_debug("using full address\n");
+ pr_debug("dest address is unicast: using full one\n");
memcpy(hc06_ptr, &hdr->daddr.s6_addr16[0], 16);
hc06_ptr += 16;
}
@@ -642,8 +636,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr)
{
struct lowpan_fragment *entry = (struct lowpan_fragment *)entry_addr;
- pr_debug("%s: timer expired for frame with tag %d\n", __func__,
- entry->tag);
+ pr_debug("timer expired for frame with tag %d\n", entry->tag);
spin_lock(&flist_lock);
list_del(&entry->list);
@@ -796,12 +789,11 @@ lowpan_process_data(struct sk_buff *skb)
_saddr = mac_cb(skb)->sa.hwaddr;
_daddr = mac_cb(skb)->da.hwaddr;
- pr_debug("(%s): iphc0 = %02x, iphc1 = %02x\n", __func__, iphc0, iphc1);
+ pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1);
/* another if the CID flag is set */
if (iphc1 & LOWPAN_IPHC_CID) {
- pr_debug("(%s): CID flag is set, increase header with one\n",
- __func__);
+ pr_debug("CID flag is set, increase header with one\n");
if (lowpan_fetch_skb_u8(skb, &num_context))
goto drop;
}
@@ -866,8 +858,8 @@ lowpan_process_data(struct sk_buff *skb)
if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr)))
goto drop;
- pr_debug("(%s): NH flag is set, next header is carried "
- "inline: %02x\n", __func__, hdr.nexthdr);
+ pr_debug("NH flag is set, next header carried inline: %02x\n",
+ hdr.nexthdr);
}
/* Hop Limit */
@@ -882,7 +874,7 @@ lowpan_process_data(struct sk_buff *skb)
tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03;
/* Source address uncompression */
- pr_debug("(%s): source address stateless compression\n", __func__);
+ pr_debug("source address stateless compression\n");
err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix,
lowpan_unc_llconf[tmp], skb->data);
if (err)
@@ -894,14 +886,12 @@ lowpan_process_data(struct sk_buff *skb)
/* check for Multicast Compression */
if (iphc1 & LOWPAN_IPHC_M) {
if (iphc1 & LOWPAN_IPHC_DAC) {
- pr_debug("(%s): destination address context-based "
- "multicast compression\n", __func__);
+ pr_debug("dest: context-based mcast compression\n");
/* TODO: implement this */
} else {
u8 prefix[] = {0xff, 0x02};
- pr_debug("(%s): destination address non-context-based"
- " multicast compression\n", __func__);
+ pr_debug("dest: non context-based mcast compression\n");
if (0 < tmp && tmp < 3) {
if (lowpan_fetch_skb_u8(skb, &prefix[1]))
goto drop;
@@ -913,8 +903,7 @@ lowpan_process_data(struct sk_buff *skb)
goto drop;
}
} else {
- pr_debug("(%s): destination address stateless compression\n",
- __func__);
+ pr_debug("dest: stateless compression\n");
err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix,
lowpan_unc_llconf[tmp], skb->data);
if (err)
@@ -929,11 +918,11 @@ lowpan_process_data(struct sk_buff *skb)
/* Not fragmented package */
hdr.payload_len = htons(skb->len);
- pr_debug("(%s): skb headroom size = %d, data length = %d\n", __func__,
- skb_headroom(skb), skb->len);
+ pr_debug("skb headroom size = %d, data length = %d\n",
+ skb_headroom(skb), skb->len);
- pr_debug("(%s): IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t"
- "nexthdr = 0x%02x\n\thop_lim = %d\n", __func__, hdr.version,
+ pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t"
+ "nexthdr = 0x%02x\n\thop_lim = %d\n", hdr.version,
ntohs(hdr.payload_len), hdr.nexthdr, hdr.hop_limit);
lowpan_raw_dump_table(__func__, "raw header dump", (u8 *)&hdr,
@@ -1035,11 +1024,11 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
{
int err = -1;
- pr_debug("(%s): package xmit\n", __func__);
+ pr_debug("package xmit\n");
skb->dev = lowpan_dev_info(dev)->real_dev;
if (skb->dev == NULL) {
- pr_debug("(%s) ERROR: no real wpan device found\n", __func__);
+ pr_debug("ERROR: no real wpan device found\n");
goto error;
}
@@ -1048,14 +1037,13 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
- pr_debug("(%s): frame is too big, fragmentation is needed\n",
- __func__);
+ pr_debug("frame is too big, fragmentation is needed\n");
err = lowpan_skb_fragmentation(skb);
error:
dev_kfree_skb(skb);
out:
if (err < 0)
- pr_debug("(%s): ERROR: xmit failed\n", __func__);
+ pr_debug("ERROR: xmit failed\n");
return (err < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK);
}
@@ -1101,8 +1089,6 @@ static struct ieee802154_mlme_ops lowpan_mlme = {
static void lowpan_setup(struct net_device *dev)
{
- pr_debug("(%s)\n", __func__);
-
dev->addr_len = IEEE802154_ADDR_LEN;
memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
dev->type = ARPHRD_IEEE802154;
@@ -1122,8 +1108,6 @@ static void lowpan_setup(struct net_device *dev)
static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[])
{
- pr_debug("(%s)\n", __func__);
-
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != IEEE802154_ADDR_LEN)
return -EINVAL;
@@ -1164,7 +1148,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
struct net_device *real_dev;
struct lowpan_dev_record *entry;
- pr_debug("(%s)\n", __func__);
+ pr_debug("adding new link\n");
if (!tb[IFLA_LINK])
return -EINVAL;
@@ -1259,8 +1243,6 @@ static int __init lowpan_init_module(void)
{
int err = 0;
- pr_debug("(%s)\n", __func__);
-
err = lowpan_netlink_init();
if (err < 0)
goto out;
@@ -1272,8 +1254,6 @@ out:
static void __exit lowpan_cleanup_module(void)
{
- pr_debug("(%s)\n", __func__);
-
lowpan_netlink_fini();
dev_remove_pack(&lowpan_packet_type);
--
1.7.2.3
^ permalink raw reply related
* [PATCH net-next v3 2/3] 6lowpan: fix hop limit compression
From: Alexander Smirnov @ 2012-06-25 13:49 UTC (permalink / raw)
To: davem; +Cc: netdev, dbaryshkov, Alexander Smirnov, Tony Cheneau
In-Reply-To: <1340632143-27794-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Add missing pointer shift for the 'default' case.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
Cc: Tony Cheneau <tony.cheneau+zigbeedev@amnesiak.org>
---
net/ieee802154/6lowpan.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 5c7bcf9..b45e229 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -492,6 +492,7 @@ static int lowpan_header_create(struct sk_buff *skb,
break;
default:
*hc06_ptr = hdr->hop_limit;
+ hc06_ptr += 1;
break;
}
--
1.7.2.3
^ permalink raw reply related
* [PATCH net-next v3 1/3] 6lowpan: read data from skb safely
From: Alexander Smirnov @ 2012-06-25 13:49 UTC (permalink / raw)
To: davem; +Cc: netdev, dbaryshkov, Alexander Smirnov
In-Reply-To: <1340632143-27794-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Check if skb buffer can pull requested amount of bytes and return
an error in opposite case.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
---
net/ieee802154/6lowpan.c | 70 +++++++++++++++++++++++++---------------------
1 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 32eb417..5c7bcf9 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -291,25 +291,26 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
*hc06_ptr += 2;
}
-static u8 lowpan_fetch_skb_u8(struct sk_buff *skb)
+static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val)
{
- u8 ret;
+ if (unlikely(!pskb_may_pull(skb, 1)))
+ return -EINVAL;
- ret = skb->data[0];
+ *val = skb->data[0];
skb_pull(skb, 1);
- return ret;
+ return 0;
}
-static u16 lowpan_fetch_skb_u16(struct sk_buff *skb)
+static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val)
{
- u16 ret;
-
- BUG_ON(!pskb_may_pull(skb, 2));
+ if (unlikely(!pskb_may_pull(skb, 2)))
+ return -EINVAL;
- ret = skb->data[0] | (skb->data[1] << 8);
+ *val = skb->data[0] | (skb->data[1] << 8);
skb_pull(skb, 2);
- return ret;
+
+ return 0;
}
static int
@@ -318,7 +319,8 @@ lowpan_uncompress_udp_header(struct sk_buff *skb)
struct udphdr *uh = udp_hdr(skb);
u8 tmp;
- tmp = lowpan_fetch_skb_u8(skb);
+ if (lowpan_fetch_skb_u8(skb, &tmp))
+ goto err;
if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
pr_debug("(%s): UDP header uncompression\n", __func__);
@@ -710,7 +712,9 @@ lowpan_process_data(struct sk_buff *skb)
/* at least two bytes will be used for the encoding */
if (skb->len < 2)
goto drop;
- iphc0 = lowpan_fetch_skb_u8(skb);
+
+ if (lowpan_fetch_skb_u8(skb, &iphc0))
+ goto drop;
/* fragments assembling */
switch (iphc0 & LOWPAN_DISPATCH_MASK) {
@@ -722,8 +726,9 @@ lowpan_process_data(struct sk_buff *skb)
u16 tag;
bool found = false;
- len = lowpan_fetch_skb_u8(skb); /* frame length */
- tag = lowpan_fetch_skb_u16(skb);
+ if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */
+ lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */
+ goto drop;
/*
* check if frame assembling with the same tag is
@@ -747,7 +752,8 @@ lowpan_process_data(struct sk_buff *skb)
if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1)
goto unlock_and_drop;
- offset = lowpan_fetch_skb_u8(skb); /* fetch offset */
+ if (lowpan_fetch_skb_u8(skb, &offset)) /* fetch offset */
+ goto unlock_and_drop;
/* if payload fits buffer, copy it */
if (likely((offset * 8 + skb->len) <= frame->length))
@@ -769,7 +775,10 @@ lowpan_process_data(struct sk_buff *skb)
dev_kfree_skb(skb);
skb = frame->skb;
kfree(frame);
- iphc0 = lowpan_fetch_skb_u8(skb);
+
+ if (lowpan_fetch_skb_u8(skb, &iphc0))
+ goto unlock_and_drop;
+
break;
}
spin_unlock(&flist_lock);
@@ -780,7 +789,8 @@ lowpan_process_data(struct sk_buff *skb)
break;
}
- iphc1 = lowpan_fetch_skb_u8(skb);
+ if (lowpan_fetch_skb_u8(skb, &iphc1))
+ goto drop;
_saddr = mac_cb(skb)->sa.hwaddr;
_daddr = mac_cb(skb)->da.hwaddr;
@@ -791,9 +801,8 @@ lowpan_process_data(struct sk_buff *skb)
if (iphc1 & LOWPAN_IPHC_CID) {
pr_debug("(%s): CID flag is set, increase header with one\n",
__func__);
- if (!skb->len)
+ if (lowpan_fetch_skb_u8(skb, &num_context))
goto drop;
- num_context = lowpan_fetch_skb_u8(skb);
}
hdr.version = 6;
@@ -805,9 +814,9 @@ lowpan_process_data(struct sk_buff *skb)
* ECN + DSCP + 4-bit Pad + Flow Label (4 bytes)
*/
case 0: /* 00b */
- if (!skb->len)
+ if (lowpan_fetch_skb_u8(skb, &tmp))
goto drop;
- tmp = lowpan_fetch_skb_u8(skb);
+
memcpy(&hdr.flow_lbl, &skb->data[0], 3);
skb_pull(skb, 3);
hdr.priority = ((tmp >> 2) & 0x0f);
@@ -819,9 +828,9 @@ lowpan_process_data(struct sk_buff *skb)
* ECN + DSCP (1 byte), Flow Label is elided
*/
case 1: /* 10b */
- if (!skb->len)
+ if (lowpan_fetch_skb_u8(skb, &tmp))
goto drop;
- tmp = lowpan_fetch_skb_u8(skb);
+
hdr.priority = ((tmp >> 2) & 0x0f);
hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30);
hdr.flow_lbl[1] = 0;
@@ -832,9 +841,9 @@ lowpan_process_data(struct sk_buff *skb)
* ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided
*/
case 2: /* 01b */
- if (!skb->len)
+ if (lowpan_fetch_skb_u8(skb, &tmp))
goto drop;
- tmp = lowpan_fetch_skb_u8(skb);
+
hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30);
memcpy(&hdr.flow_lbl[1], &skb->data[0], 2);
skb_pull(skb, 2);
@@ -853,9 +862,9 @@ lowpan_process_data(struct sk_buff *skb)
/* Next Header */
if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) {
/* Next header is carried inline */
- if (!skb->len)
+ if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr)))
goto drop;
- hdr.nexthdr = lowpan_fetch_skb_u8(skb);
+
pr_debug("(%s): NH flag is set, next header is carried "
"inline: %02x\n", __func__, hdr.nexthdr);
}
@@ -864,9 +873,8 @@ lowpan_process_data(struct sk_buff *skb)
if ((iphc0 & 0x03) != LOWPAN_IPHC_TTL_I)
hdr.hop_limit = lowpan_ttl_values[iphc0 & 0x03];
else {
- if (!skb->len)
+ if (lowpan_fetch_skb_u8(skb, &(hdr.hop_limit)))
goto drop;
- hdr.hop_limit = lowpan_fetch_skb_u8(skb);
}
/* Extract SAM to the tmp variable */
@@ -894,10 +902,8 @@ lowpan_process_data(struct sk_buff *skb)
pr_debug("(%s): destination address non-context-based"
" multicast compression\n", __func__);
if (0 < tmp && tmp < 3) {
- if (!skb->len)
+ if (lowpan_fetch_skb_u8(skb, &prefix[1]))
goto drop;
- else
- prefix[1] = lowpan_fetch_skb_u8(skb);
}
err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix,
--
1.7.2.3
^ permalink raw reply related
* [PATCH 0/3 v3 resend] 6lowpan: minor fixes
From: Alexander Smirnov @ 2012-06-25 13:49 UTC (permalink / raw)
To: davem; +Cc: netdev, dbaryshkov
Hello David,
I sent this set several weeks ago and seems that it was missed
(or please let me know if there was a reason).
this is the 3-rd version of the patches.
Changes since v2:
- Removed WARN_ON() and BUG() from skb fetch methods. That wasn't a good idea
to crash kernel by such an unsignificant issue.
- Added new patch (I've decided to add it here just to keep all the 6lowpan
related code together)
Could you please review this set?
Thank you for your time!
With best regards,
Alexander Smirnov
Alexander Smirnov (3):
6lowpan: read data from skb safely
6lowpan: fix hop limit compression
6lowpan: remove excessive argument in pr_debug
net/ieee802154/6lowpan.c | 163 ++++++++++++++++++++++------------------------
1 files changed, 78 insertions(+), 85 deletions(-)
--
1.7.2.3
^ permalink raw reply
* Re: [PATCH fix] mac802154: add missed braces
From: Alexander Smirnov @ 2012-06-25 13:46 UTC (permalink / raw)
To: davem; +Cc: netdev, Alexander Smirnov
In-Reply-To: <1340631013-27556-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Sorry, forgot the tag, this patch is for the "net" tree.
^ permalink raw reply
* [PATCH 7/7] mac802154: add monitor listener to TX datapath
From: Alexander Smirnov @ 2012-06-25 13:33 UTC (permalink / raw)
To: davem; +Cc: netdev, dbaryshkov, Alexander Smirnov
In-Reply-To: <1340631197-27691-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Add monitor receive callback to the TX datapath to catch all the
data sent to transceivers.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
---
net/mac802154/tx.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 434b687..1a4df39 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -88,6 +88,8 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
return NETDEV_TX_OK;
}
+ mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb);
+
if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) {
u16 crc = crc_ccitt(0, skb->data, skb->len);
u8 *data = skb_put(skb, 2);
--
1.7.2.3
^ permalink raw reply related
* [PATCH 6/7] drivers/ieee802154: add support for the at86rf230/231 transceivers
From: Alexander Smirnov @ 2012-06-25 13:33 UTC (permalink / raw)
To: davem; +Cc: netdev, dbaryshkov, Alexander Smirnov
In-Reply-To: <1340631197-27691-1-git-send-email-alex.bluesman.smirnov@gmail.com>
The AT86RF231 is a feature rich, low-power 2.4 GHz radio transceiver
designed for industrial and consumer ZigBee/IEEE 802.15.4, 6LoWPAN,
RF4CE and high data rate 2.4 GHz ISM band applications.
This patch adds support for the Atmel RF230/231 radio transceivers.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
---
drivers/ieee802154/Kconfig | 6 +
drivers/ieee802154/Makefile | 1 +
drivers/ieee802154/at86rf230.c | 966 ++++++++++++++++++++++++++++++++++++++++
include/linux/spi/at86rf230.h | 32 ++
4 files changed, 1005 insertions(+), 0 deletions(-)
create mode 100644 drivers/ieee802154/at86rf230.c
create mode 100644 include/linux/spi/at86rf230.h
diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig
index 15c0640..1fc4eef 100644
--- a/drivers/ieee802154/Kconfig
+++ b/drivers/ieee802154/Kconfig
@@ -19,6 +19,7 @@ config IEEE802154_FAKEHARD
This driver can also be built as a module. To do so say M here.
The module will be called 'fakehard'.
+
config IEEE802154_FAKELB
depends on IEEE802154_DRIVERS && MAC802154
tristate "IEEE 802.15.4 loopback driver"
@@ -28,3 +29,8 @@ config IEEE802154_FAKELB
This driver can also be built as a module. To do so say M here.
The module will be called 'fakelb'.
+
+config IEEE802154_AT86RF230
+ depends on IEEE802154_DRIVERS && MAC802154
+ tristate "AT86RF230/231 transceiver driver"
+ depends on SPI
diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile
index ea784ea..4f4371d 100644
--- a/drivers/ieee802154/Makefile
+++ b/drivers/ieee802154/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
+obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
diff --git a/drivers/ieee802154/at86rf230.c b/drivers/ieee802154/at86rf230.c
new file mode 100644
index 0000000..2b52374
--- /dev/null
+++ b/drivers/ieee802154/at86rf230.c
@@ -0,0 +1,966 @@
+/*
+ * AT86RF230/RF231 driver
+ *
+ * Copyright (C) 2009-2012 Siemens AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/at86rf230.h>
+#include <linux/skbuff.h>
+
+#include <net/mac802154.h>
+#include <net/wpan-phy.h>
+
+struct at86rf230_local {
+ struct spi_device *spi;
+ int rstn, slp_tr, dig2;
+
+ u8 part;
+ u8 vers;
+
+ u8 buf[2];
+ struct mutex bmux;
+
+ struct work_struct irqwork;
+ struct completion tx_complete;
+
+ struct ieee802154_dev *dev;
+
+ spinlock_t lock;
+ bool irq_disabled;
+ bool is_tx;
+};
+
+#define RG_TRX_STATUS (0x01)
+#define SR_TRX_STATUS 0x01, 0x1f, 0
+#define SR_RESERVED_01_3 0x01, 0x20, 5
+#define SR_CCA_STATUS 0x01, 0x40, 6
+#define SR_CCA_DONE 0x01, 0x80, 7
+#define RG_TRX_STATE (0x02)
+#define SR_TRX_CMD 0x02, 0x1f, 0
+#define SR_TRAC_STATUS 0x02, 0xe0, 5
+#define RG_TRX_CTRL_0 (0x03)
+#define SR_CLKM_CTRL 0x03, 0x07, 0
+#define SR_CLKM_SHA_SEL 0x03, 0x08, 3
+#define SR_PAD_IO_CLKM 0x03, 0x30, 4
+#define SR_PAD_IO 0x03, 0xc0, 6
+#define RG_TRX_CTRL_1 (0x04)
+#define SR_IRQ_POLARITY 0x04, 0x01, 0
+#define SR_IRQ_MASK_MODE 0x04, 0x02, 1
+#define SR_SPI_CMD_MODE 0x04, 0x0c, 2
+#define SR_RX_BL_CTRL 0x04, 0x10, 4
+#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5
+#define SR_IRQ_2_EXT_EN 0x04, 0x40, 6
+#define SR_PA_EXT_EN 0x04, 0x80, 7
+#define RG_PHY_TX_PWR (0x05)
+#define SR_TX_PWR 0x05, 0x0f, 0
+#define SR_PA_LT 0x05, 0x30, 4
+#define SR_PA_BUF_LT 0x05, 0xc0, 6
+#define RG_PHY_RSSI (0x06)
+#define SR_RSSI 0x06, 0x1f, 0
+#define SR_RND_VALUE 0x06, 0x60, 5
+#define SR_RX_CRC_VALID 0x06, 0x80, 7
+#define RG_PHY_ED_LEVEL (0x07)
+#define SR_ED_LEVEL 0x07, 0xff, 0
+#define RG_PHY_CC_CCA (0x08)
+#define SR_CHANNEL 0x08, 0x1f, 0
+#define SR_CCA_MODE 0x08, 0x60, 5
+#define SR_CCA_REQUEST 0x08, 0x80, 7
+#define RG_CCA_THRES (0x09)
+#define SR_CCA_ED_THRES 0x09, 0x0f, 0
+#define SR_RESERVED_09_1 0x09, 0xf0, 4
+#define RG_RX_CTRL (0x0a)
+#define SR_PDT_THRES 0x0a, 0x0f, 0
+#define SR_RESERVED_0a_1 0x0a, 0xf0, 4
+#define RG_SFD_VALUE (0x0b)
+#define SR_SFD_VALUE 0x0b, 0xff, 0
+#define RG_TRX_CTRL_2 (0x0c)
+#define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0
+#define SR_RESERVED_0c_2 0x0c, 0x7c, 2
+#define SR_RX_SAFE_MODE 0x0c, 0x80, 7
+#define RG_ANT_DIV (0x0d)
+#define SR_ANT_CTRL 0x0d, 0x03, 0
+#define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2
+#define SR_ANT_DIV_EN 0x0d, 0x08, 3
+#define SR_RESERVED_0d_2 0x0d, 0x70, 4
+#define SR_ANT_SEL 0x0d, 0x80, 7
+#define RG_IRQ_MASK (0x0e)
+#define SR_IRQ_MASK 0x0e, 0xff, 0
+#define RG_IRQ_STATUS (0x0f)
+#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0
+#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1
+#define SR_IRQ_2_RX_START 0x0f, 0x04, 2
+#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3
+#define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4
+#define SR_IRQ_5_AMI 0x0f, 0x20, 5
+#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6
+#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7
+#define RG_VREG_CTRL (0x10)
+#define SR_RESERVED_10_6 0x10, 0x03, 0
+#define SR_DVDD_OK 0x10, 0x04, 2
+#define SR_DVREG_EXT 0x10, 0x08, 3
+#define SR_RESERVED_10_3 0x10, 0x30, 4
+#define SR_AVDD_OK 0x10, 0x40, 6
+#define SR_AVREG_EXT 0x10, 0x80, 7
+#define RG_BATMON (0x11)
+#define SR_BATMON_VTH 0x11, 0x0f, 0
+#define SR_BATMON_HR 0x11, 0x10, 4
+#define SR_BATMON_OK 0x11, 0x20, 5
+#define SR_RESERVED_11_1 0x11, 0xc0, 6
+#define RG_XOSC_CTRL (0x12)
+#define SR_XTAL_TRIM 0x12, 0x0f, 0
+#define SR_XTAL_MODE 0x12, 0xf0, 4
+#define RG_RX_SYN (0x15)
+#define SR_RX_PDT_LEVEL 0x15, 0x0f, 0
+#define SR_RESERVED_15_2 0x15, 0x70, 4
+#define SR_RX_PDT_DIS 0x15, 0x80, 7
+#define RG_XAH_CTRL_1 (0x17)
+#define SR_RESERVED_17_8 0x17, 0x01, 0
+#define SR_AACK_PROM_MODE 0x17, 0x02, 1
+#define SR_AACK_ACK_TIME 0x17, 0x04, 2
+#define SR_RESERVED_17_5 0x17, 0x08, 3
+#define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4
+#define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5
+#define SR_RESERVED_17_2 0x17, 0x40, 6
+#define SR_RESERVED_17_1 0x17, 0x80, 7
+#define RG_FTN_CTRL (0x18)
+#define SR_RESERVED_18_2 0x18, 0x7f, 0
+#define SR_FTN_START 0x18, 0x80, 7
+#define RG_PLL_CF (0x1a)
+#define SR_RESERVED_1a_2 0x1a, 0x7f, 0
+#define SR_PLL_CF_START 0x1a, 0x80, 7
+#define RG_PLL_DCU (0x1b)
+#define SR_RESERVED_1b_3 0x1b, 0x3f, 0
+#define SR_RESERVED_1b_2 0x1b, 0x40, 6
+#define SR_PLL_DCU_START 0x1b, 0x80, 7
+#define RG_PART_NUM (0x1c)
+#define SR_PART_NUM 0x1c, 0xff, 0
+#define RG_VERSION_NUM (0x1d)
+#define SR_VERSION_NUM 0x1d, 0xff, 0
+#define RG_MAN_ID_0 (0x1e)
+#define SR_MAN_ID_0 0x1e, 0xff, 0
+#define RG_MAN_ID_1 (0x1f)
+#define SR_MAN_ID_1 0x1f, 0xff, 0
+#define RG_SHORT_ADDR_0 (0x20)
+#define SR_SHORT_ADDR_0 0x20, 0xff, 0
+#define RG_SHORT_ADDR_1 (0x21)
+#define SR_SHORT_ADDR_1 0x21, 0xff, 0
+#define RG_PAN_ID_0 (0x22)
+#define SR_PAN_ID_0 0x22, 0xff, 0
+#define RG_PAN_ID_1 (0x23)
+#define SR_PAN_ID_1 0x23, 0xff, 0
+#define RG_IEEE_ADDR_0 (0x24)
+#define SR_IEEE_ADDR_0 0x24, 0xff, 0
+#define RG_IEEE_ADDR_1 (0x25)
+#define SR_IEEE_ADDR_1 0x25, 0xff, 0
+#define RG_IEEE_ADDR_2 (0x26)
+#define SR_IEEE_ADDR_2 0x26, 0xff, 0
+#define RG_IEEE_ADDR_3 (0x27)
+#define SR_IEEE_ADDR_3 0x27, 0xff, 0
+#define RG_IEEE_ADDR_4 (0x28)
+#define SR_IEEE_ADDR_4 0x28, 0xff, 0
+#define RG_IEEE_ADDR_5 (0x29)
+#define SR_IEEE_ADDR_5 0x29, 0xff, 0
+#define RG_IEEE_ADDR_6 (0x2a)
+#define SR_IEEE_ADDR_6 0x2a, 0xff, 0
+#define RG_IEEE_ADDR_7 (0x2b)
+#define SR_IEEE_ADDR_7 0x2b, 0xff, 0
+#define RG_XAH_CTRL_0 (0x2c)
+#define SR_SLOTTED_OPERATION 0x2c, 0x01, 0
+#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1
+#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4
+#define RG_CSMA_SEED_0 (0x2d)
+#define SR_CSMA_SEED_0 0x2d, 0xff, 0
+#define RG_CSMA_SEED_1 (0x2e)
+#define SR_CSMA_SEED_1 0x2e, 0x07, 0
+#define SR_AACK_I_AM_COORD 0x2e, 0x08, 3
+#define SR_AACK_DIS_ACK 0x2e, 0x10, 4
+#define SR_AACK_SET_PD 0x2e, 0x20, 5
+#define SR_AACK_FVN_MODE 0x2e, 0xc0, 6
+#define RG_CSMA_BE (0x2f)
+#define SR_MIN_BE 0x2f, 0x0f, 0
+#define SR_MAX_BE 0x2f, 0xf0, 4
+
+#define CMD_REG 0x80
+#define CMD_REG_MASK 0x3f
+#define CMD_WRITE 0x40
+#define CMD_FB 0x20
+
+#define IRQ_BAT_LOW (1 << 7)
+#define IRQ_TRX_UR (1 << 6)
+#define IRQ_AMI (1 << 5)
+#define IRQ_CCA_ED (1 << 4)
+#define IRQ_TRX_END (1 << 3)
+#define IRQ_RX_START (1 << 2)
+#define IRQ_PLL_UNL (1 << 1)
+#define IRQ_PLL_LOCK (1 << 0)
+
+#define STATE_P_ON 0x00 /* BUSY */
+#define STATE_BUSY_RX 0x01
+#define STATE_BUSY_TX 0x02
+#define STATE_FORCE_TRX_OFF 0x03
+#define STATE_FORCE_TX_ON 0x04 /* IDLE */
+/* 0x05 */ /* INVALID_PARAMETER */
+#define STATE_RX_ON 0x06
+/* 0x07 */ /* SUCCESS */
+#define STATE_TRX_OFF 0x08
+#define STATE_TX_ON 0x09
+/* 0x0a - 0x0e */ /* 0x0a - UNSUPPORTED_ATTRIBUTE */
+#define STATE_SLEEP 0x0F
+#define STATE_BUSY_RX_AACK 0x11
+#define STATE_BUSY_TX_ARET 0x12
+#define STATE_BUSY_RX_AACK_ON 0x16
+#define STATE_BUSY_TX_ARET_ON 0x19
+#define STATE_RX_ON_NOCLK 0x1C
+#define STATE_RX_AACK_ON_NOCLK 0x1D
+#define STATE_BUSY_RX_AACK_NOCLK 0x1E
+#define STATE_TRANSITION_IN_PROGRESS 0x1F
+
+static int
+__at86rf230_write(struct at86rf230_local *lp, u8 addr, u8 data)
+{
+ u8 *buf = lp->buf;
+ int status;
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = 2,
+ .tx_buf = buf,
+ };
+
+ buf[0] = (addr & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
+ buf[1] = data;
+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ status = spi_sync(lp->spi, &msg);
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ if (msg.status)
+ status = msg.status;
+
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
+
+ return status;
+}
+
+static int
+__at86rf230_read_subreg(struct at86rf230_local *lp,
+ u8 addr, u8 mask, int shift, u8 *data)
+{
+ u8 *buf = lp->buf;
+ int status;
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = 2,
+ .tx_buf = buf,
+ .rx_buf = buf,
+ };
+
+ buf[0] = (addr & CMD_REG_MASK) | CMD_REG;
+ buf[1] = 0xff;
+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ status = spi_sync(lp->spi, &msg);
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ if (msg.status)
+ status = msg.status;
+
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
+
+ if (status == 0)
+ *data = buf[1];
+
+ return status;
+}
+
+static int
+at86rf230_read_subreg(struct at86rf230_local *lp,
+ u8 addr, u8 mask, int shift, u8 *data)
+{
+ int status;
+
+ mutex_lock(&lp->bmux);
+ status = __at86rf230_read_subreg(lp, addr, mask, shift, data);
+ mutex_unlock(&lp->bmux);
+
+ return status;
+}
+
+static int
+at86rf230_write_subreg(struct at86rf230_local *lp,
+ u8 addr, u8 mask, int shift, u8 data)
+{
+ int status;
+ u8 val;
+
+ mutex_lock(&lp->bmux);
+ status = __at86rf230_read_subreg(lp, addr, 0xff, 0, &val);
+ if (status)
+ goto out;
+
+ val &= ~mask;
+ val |= (data << shift) & mask;
+
+ status = __at86rf230_write(lp, addr, val);
+out:
+ mutex_unlock(&lp->bmux);
+
+ return status;
+}
+
+static int
+at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len)
+{
+ u8 *buf = lp->buf;
+ int status;
+ struct spi_message msg;
+ struct spi_transfer xfer_head = {
+ .len = 2,
+ .tx_buf = buf,
+
+ };
+ struct spi_transfer xfer_buf = {
+ .len = len,
+ .tx_buf = data,
+ };
+
+ mutex_lock(&lp->bmux);
+ buf[0] = CMD_WRITE | CMD_FB;
+ buf[1] = len + 2; /* 2 bytes for CRC that isn't written */
+
+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer_head, &msg);
+ spi_message_add_tail(&xfer_buf, &msg);
+
+ status = spi_sync(lp->spi, &msg);
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ if (msg.status)
+ status = msg.status;
+
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
+
+ mutex_unlock(&lp->bmux);
+ return status;
+}
+
+static int
+at86rf230_read_fbuf(struct at86rf230_local *lp, u8 *data, u8 *len, u8 *lqi)
+{
+ u8 *buf = lp->buf;
+ int status;
+ struct spi_message msg;
+ struct spi_transfer xfer_head = {
+ .len = 2,
+ .tx_buf = buf,
+ .rx_buf = buf,
+ };
+ struct spi_transfer xfer_head1 = {
+ .len = 2,
+ .tx_buf = buf,
+ .rx_buf = buf,
+ };
+ struct spi_transfer xfer_buf = {
+ .len = 0,
+ .rx_buf = data,
+ };
+
+ mutex_lock(&lp->bmux);
+
+ buf[0] = CMD_FB;
+ buf[1] = 0x00;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer_head, &msg);
+
+ status = spi_sync(lp->spi, &msg);
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+
+ xfer_buf.len = *(buf + 1) + 1;
+ *len = buf[1];
+
+ buf[0] = CMD_FB;
+ buf[1] = 0x00;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer_head1, &msg);
+ spi_message_add_tail(&xfer_buf, &msg);
+
+ status = spi_sync(lp->spi, &msg);
+
+ if (msg.status)
+ status = msg.status;
+
+ dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
+ dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
+
+ if (status) {
+ if (lqi && (*len > lp->buf[1]))
+ *lqi = data[lp->buf[1]];
+ }
+ mutex_unlock(&lp->bmux);
+
+ return status;
+}
+
+static int
+at86rf230_ed(struct ieee802154_dev *dev, u8 *level)
+{
+ might_sleep();
+ BUG_ON(!level);
+ *level = 0xbe;
+ return 0;
+}
+
+static int
+at86rf230_state(struct ieee802154_dev *dev, int state)
+{
+ struct at86rf230_local *lp = dev->priv;
+ int rc;
+ u8 val;
+ u8 desired_status;
+
+ might_sleep();
+
+ if (state == STATE_FORCE_TX_ON)
+ desired_status = STATE_TX_ON;
+ else if (state == STATE_FORCE_TRX_OFF)
+ desired_status = STATE_TRX_OFF;
+ else
+ desired_status = state;
+
+ do {
+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
+ if (rc)
+ goto err;
+ } while (val == STATE_TRANSITION_IN_PROGRESS);
+
+ if (val == desired_status)
+ return 0;
+
+ /* state is equal to phy states */
+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, state);
+ if (rc)
+ goto err;
+
+ do {
+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
+ if (rc)
+ goto err;
+ } while (val == STATE_TRANSITION_IN_PROGRESS);
+
+
+ if (val == desired_status)
+ return 0;
+
+ pr_err("unexpected state change: %d, asked for %d\n", val, state);
+ return -EBUSY;
+
+err:
+ pr_err("error: %d\n", rc);
+ return rc;
+}
+
+static int
+at86rf230_start(struct ieee802154_dev *dev)
+{
+ struct at86rf230_local *lp = dev->priv;
+ u8 rc;
+
+ rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1);
+ if (rc)
+ return rc;
+
+ return at86rf230_state(dev, STATE_RX_ON);
+}
+
+static void
+at86rf230_stop(struct ieee802154_dev *dev)
+{
+ at86rf230_state(dev, STATE_FORCE_TRX_OFF);
+}
+
+static int
+at86rf230_channel(struct ieee802154_dev *dev, int page, int channel)
+{
+ struct at86rf230_local *lp = dev->priv;
+ int rc;
+
+ might_sleep();
+
+ if (page != 0 || channel < 11 || channel > 26) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ rc = at86rf230_write_subreg(lp, SR_CHANNEL, channel);
+ msleep(1); /* Wait for PLL */
+ dev->phy->current_channel = channel;
+
+ return 0;
+}
+
+static int
+at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
+{
+ struct at86rf230_local *lp = dev->priv;
+ int rc;
+ unsigned long flags;
+
+ might_sleep();
+
+ rc = at86rf230_state(dev, STATE_FORCE_TX_ON);
+ if (rc)
+ goto err;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ lp->is_tx = 1;
+ INIT_COMPLETION(lp->tx_complete);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ rc = at86rf230_write_fbuf(lp, skb->data, skb->len);
+ if (rc)
+ goto err_rx;
+
+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_BUSY_TX);
+ if (rc)
+ goto err_rx;
+
+ rc = wait_for_completion_interruptible(&lp->tx_complete);
+ if (rc < 0)
+ goto err_rx;
+
+ rc = at86rf230_start(dev);
+
+ return rc;
+
+err_rx:
+ at86rf230_start(dev);
+err:
+ pr_err("error: %d\n", rc);
+
+ spin_lock_irqsave(&lp->lock, flags);
+ lp->is_tx = 0;
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ return rc;
+}
+
+static int at86rf230_rx(struct at86rf230_local *lp)
+{
+ u8 len = 128, lqi = 0;
+ int rc;
+ struct sk_buff *skb;
+
+ skb = alloc_skb(len, GFP_KERNEL);
+
+ if (!skb)
+ return -ENOMEM;
+
+ if (at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 1) ||
+ at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi) ||
+ at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1) ||
+ at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 0)) {
+ goto err;
+ }
+
+ if (len < 2)
+ goto err;
+
+ skb_trim(skb, len - 2); /* We do not put CRC into the frame */
+
+ ieee802154_rx_irqsafe(lp->dev, skb, lqi);
+
+ dev_dbg(&lp->spi->dev, "READ_FBUF: %d %d %x\n", rc, len, lqi);
+
+ return 0;
+err:
+ pr_debug("received frame is too small\n");
+
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+static struct ieee802154_ops at86rf230_ops = {
+ .owner = THIS_MODULE,
+ .xmit = at86rf230_xmit,
+ .ed = at86rf230_ed,
+ .set_channel = at86rf230_channel,
+ .start = at86rf230_start,
+ .stop = at86rf230_stop,
+};
+
+static void at86rf230_irqwork(struct work_struct *work)
+{
+ struct at86rf230_local *lp =
+ container_of(work, struct at86rf230_local, irqwork);
+ u8 status = 0, val;
+ int rc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &val);
+ status |= val;
+
+ status &= ~IRQ_PLL_LOCK; /* ignore */
+ status &= ~IRQ_RX_START; /* ignore */
+ status &= ~IRQ_AMI; /* ignore */
+ status &= ~IRQ_TRX_UR; /* FIXME: possibly handle ???*/
+
+ if (status & IRQ_TRX_END) {
+ status &= ~IRQ_TRX_END;
+ if (lp->is_tx) {
+ lp->is_tx = 0;
+ complete(&lp->tx_complete);
+ } else {
+ at86rf230_rx(lp);
+ }
+ }
+
+ if (lp->irq_disabled) {
+ lp->irq_disabled = 0;
+ enable_irq(lp->spi->irq);
+ }
+ spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+static irqreturn_t at86rf230_isr(int irq, void *data)
+{
+ struct at86rf230_local *lp = data;
+
+ spin_lock(&lp->lock);
+ if (!lp->irq_disabled) {
+ disable_irq_nosync(irq);
+ lp->irq_disabled = 1;
+ }
+ spin_unlock(&lp->lock);
+
+ schedule_work(&lp->irqwork);
+
+ return IRQ_HANDLED;
+}
+
+
+static int at86rf230_hw_init(struct at86rf230_local *lp)
+{
+ u8 status;
+ int rc;
+
+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
+ if (rc)
+ return rc;
+
+ dev_info(&lp->spi->dev, "Status: %02x\n", status);
+ if (status == STATE_P_ON) {
+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TRX_OFF);
+ if (rc)
+ return rc;
+ msleep(1);
+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
+ if (rc)
+ return rc;
+ dev_info(&lp->spi->dev, "Status: %02x\n", status);
+ }
+
+ rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, 0xff); /* IRQ_TRX_UR |
+ * IRQ_CCA_ED |
+ * IRQ_TRX_END |
+ * IRQ_PLL_UNL |
+ * IRQ_PLL_LOCK
+ */
+ if (rc)
+ return rc;
+
+ /* CLKM changes are applied immediately */
+ rc = at86rf230_write_subreg(lp, SR_CLKM_SHA_SEL, 0x00);
+ if (rc)
+ return rc;
+
+ /* Turn CLKM Off */
+ rc = at86rf230_write_subreg(lp, SR_CLKM_CTRL, 0x00);
+ if (rc)
+ return rc;
+ /* Wait the next SLEEP cycle */
+ msleep(100);
+
+ rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TX_ON);
+ if (rc)
+ return rc;
+ msleep(1);
+
+ rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
+ if (rc)
+ return rc;
+ dev_info(&lp->spi->dev, "Status: %02x\n", status);
+
+ rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &status);
+ if (rc)
+ return rc;
+ if (!status) {
+ dev_err(&lp->spi->dev, "DVDD error\n");
+ return -EINVAL;
+ }
+
+ rc = at86rf230_read_subreg(lp, SR_AVDD_OK, &status);
+ if (rc)
+ return rc;
+ if (!status) {
+ dev_err(&lp->spi->dev, "AVDD error\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int at86rf230_suspend(struct spi_device *spi, pm_message_t message)
+{
+ return 0;
+}
+
+static int at86rf230_resume(struct spi_device *spi)
+{
+ return 0;
+}
+
+static int at86rf230_fill_data(struct spi_device *spi)
+{
+ struct at86rf230_local *lp = spi_get_drvdata(spi);
+ struct at86rf230_platform_data *pdata = spi->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&spi->dev, "no platform_data\n");
+ return -EINVAL;
+ }
+
+ lp->rstn = pdata->rstn;
+ lp->slp_tr = pdata->slp_tr;
+ lp->dig2 = pdata->dig2;
+
+ return 0;
+}
+
+static int __devinit at86rf230_probe(struct spi_device *spi)
+{
+ struct ieee802154_dev *dev;
+ struct at86rf230_local *lp;
+ u8 man_id_0, man_id_1;
+ int rc;
+ const char *chip;
+ int supported = 0;
+
+ if (!spi->irq) {
+ dev_err(&spi->dev, "no IRQ specified\n");
+ return -EINVAL;
+ }
+
+ dev = ieee802154_alloc_device(sizeof(*lp), &at86rf230_ops);
+ if (!dev)
+ return -ENOMEM;
+
+ lp = dev->priv;
+ lp->dev = dev;
+
+ lp->spi = spi;
+
+ dev->priv = lp;
+ dev->parent = &spi->dev;
+ dev->extra_tx_headroom = 0;
+ /* We do support only 2.4 Ghz */
+ dev->phy->channels_supported[0] = 0x7FFF800;
+ dev->flags = IEEE802154_HW_OMIT_CKSUM;
+
+ mutex_init(&lp->bmux);
+ INIT_WORK(&lp->irqwork, at86rf230_irqwork);
+ spin_lock_init(&lp->lock);
+ init_completion(&lp->tx_complete);
+
+ spi_set_drvdata(spi, lp);
+
+ rc = at86rf230_fill_data(spi);
+ if (rc)
+ goto err_fill;
+
+ rc = gpio_request(lp->rstn, "rstn");
+ if (rc)
+ goto err_rstn;
+
+ if (gpio_is_valid(lp->slp_tr)) {
+ rc = gpio_request(lp->slp_tr, "slp_tr");
+ if (rc)
+ goto err_slp_tr;
+ }
+
+ rc = gpio_direction_output(lp->rstn, 1);
+ if (rc)
+ goto err_gpio_dir;
+
+ if (gpio_is_valid(lp->slp_tr)) {
+ rc = gpio_direction_output(lp->slp_tr, 0);
+ if (rc)
+ goto err_gpio_dir;
+ }
+
+ /* Reset */
+ msleep(1);
+ gpio_set_value(lp->rstn, 0);
+ msleep(1);
+ gpio_set_value(lp->rstn, 1);
+ msleep(1);
+
+ rc = at86rf230_read_subreg(lp, SR_MAN_ID_0, &man_id_0);
+ if (rc)
+ goto err_gpio_dir;
+ rc = at86rf230_read_subreg(lp, SR_MAN_ID_1, &man_id_1);
+ if (rc)
+ goto err_gpio_dir;
+
+ if (man_id_1 != 0x00 || man_id_0 != 0x1f) {
+ dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
+ man_id_1, man_id_0);
+ rc = -EINVAL;
+ goto err_gpio_dir;
+ }
+
+ rc = at86rf230_read_subreg(lp, SR_PART_NUM, &lp->part);
+ if (rc)
+ goto err_gpio_dir;
+
+ rc = at86rf230_read_subreg(lp, SR_VERSION_NUM, &lp->vers);
+ if (rc)
+ goto err_gpio_dir;
+
+ switch (lp->part) {
+ case 2:
+ chip = "at86rf230";
+ /* supported = 1; FIXME: should be easy to support; */
+ break;
+ case 3:
+ chip = "at86rf231";
+ supported = 1;
+ break;
+ default:
+ chip = "UNKNOWN";
+ break;
+ }
+
+ dev_info(&spi->dev, "Detected %s chip version %d\n", chip, lp->vers);
+ if (!supported) {
+ rc = -ENOTSUPP;
+ goto err_gpio_dir;
+ }
+
+ rc = at86rf230_hw_init(lp);
+ if (rc)
+ goto err_gpio_dir;
+
+ rc = request_irq(spi->irq, at86rf230_isr, IRQF_SHARED,
+ dev_name(&spi->dev), lp);
+ if (rc)
+ goto err_gpio_dir;
+
+ rc = ieee802154_register_device(lp->dev);
+ if (rc)
+ goto err_irq;
+
+ return rc;
+
+ ieee802154_unregister_device(lp->dev);
+err_irq:
+ free_irq(spi->irq, lp);
+ flush_work(&lp->irqwork);
+err_gpio_dir:
+ if (gpio_is_valid(lp->slp_tr))
+ gpio_free(lp->slp_tr);
+err_slp_tr:
+ gpio_free(lp->rstn);
+err_rstn:
+err_fill:
+ spi_set_drvdata(spi, NULL);
+ mutex_destroy(&lp->bmux);
+ ieee802154_free_device(lp->dev);
+ return rc;
+}
+
+static int __devexit at86rf230_remove(struct spi_device *spi)
+{
+ struct at86rf230_local *lp = spi_get_drvdata(spi);
+
+ ieee802154_unregister_device(lp->dev);
+
+ free_irq(spi->irq, lp);
+ flush_work(&lp->irqwork);
+
+ if (gpio_is_valid(lp->slp_tr))
+ gpio_free(lp->slp_tr);
+ gpio_free(lp->rstn);
+
+ spi_set_drvdata(spi, NULL);
+ mutex_destroy(&lp->bmux);
+ ieee802154_free_device(lp->dev);
+
+ dev_dbg(&spi->dev, "unregistered at86rf230\n");
+ return 0;
+}
+
+static struct spi_driver at86rf230_driver = {
+ .driver = {
+ .name = "at86rf230",
+ .owner = THIS_MODULE,
+ },
+ .probe = at86rf230_probe,
+ .remove = __devexit_p(at86rf230_remove),
+ .suspend = at86rf230_suspend,
+ .resume = at86rf230_resume,
+};
+
+static int __init at86rf230_init(void)
+{
+ return spi_register_driver(&at86rf230_driver);
+}
+module_init(at86rf230_init);
+
+static void __exit at86rf230_exit(void)
+{
+ spi_unregister_driver(&at86rf230_driver);
+}
+module_exit(at86rf230_exit);
+
+MODULE_DESCRIPTION("AT86RF230 Transceiver Driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h
new file mode 100644
index 0000000..958f88d
--- /dev/null
+++ b/include/linux/spi/at86rf230.h
@@ -0,0 +1,32 @@
+/*
+ * AT86RF230/RF231 driver
+ *
+ * Copyright (C) 2009-2012 Siemens AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
+ */
+#ifndef AT86RF230_H
+#define AT86RF230_H
+
+struct at86rf230_platform_data {
+ int rstn;
+ int slp_tr;
+ int dig2;
+};
+
+#endif
+
--
1.7.2.3
^ permalink raw reply related
* [PATCH 5/7] mac802154: mlme start request
From: Alexander Smirnov @ 2012-06-25 13:33 UTC (permalink / raw)
To: davem; +Cc: netdev, dbaryshkov, Alexander Smirnov
In-Reply-To: <1340631197-27691-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Basic preparations to start the interface.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
---
net/mac802154/mac_cmd.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
index db83419..7f5403e 100644
--- a/net/mac802154/mac_cmd.c
+++ b/net/mac802154/mac_cmd.c
@@ -25,12 +25,36 @@
#include <linux/skbuff.h>
#include <linux/if_arp.h>
+#include <net/ieee802154.h>
#include <net/ieee802154_netdev.h>
#include <net/wpan-phy.h>
#include <net/mac802154.h>
+#include <net/nl802154.h>
#include "mac802154.h"
+static int mac802154_mlme_start_req(struct net_device *dev,
+ struct ieee802154_addr *addr,
+ u8 channel, u8 page,
+ u8 bcn_ord, u8 sf_ord,
+ u8 pan_coord, u8 blx,
+ u8 coord_realign)
+{
+ BUG_ON(addr->addr_type != IEEE802154_ADDR_SHORT);
+
+ mac802154_dev_set_pan_id(dev, addr->pan_id);
+ mac802154_dev_set_short_addr(dev, addr->short_addr);
+ mac802154_dev_set_ieee_addr(dev);
+ mac802154_dev_set_page_channel(dev, page, channel);
+
+ /* FIXME: add validation for unused parameters to be sane
+ * for SoftMAC
+ */
+ ieee802154_nl_start_confirm(dev, IEEE802154_SUCCESS);
+
+ return 0;
+}
+
struct wpan_phy *mac802154_get_phy(const struct net_device *dev)
{
struct mac802154_sub_if_data *priv = netdev_priv(dev);
@@ -46,4 +70,5 @@ struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced = {
struct ieee802154_mlme_ops mac802154_mlme_wpan = {
.get_phy = mac802154_get_phy,
+ .start_req = mac802154_mlme_start_req,
};
--
1.7.2.3
^ 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