Netdev List
 help / color / mirror / Atom feed
* Re: pull request: sfc-next-2.6 2011-02-18
From: David Miller @ 2011-02-22 18:22 UTC (permalink / raw)
  To: bhutchings; +Cc: netdev, linux-net-drivers, therbert
In-Reply-To: <1298044839.2570.7.camel@bwh-desktop>

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 18 Feb 2011 16:00:39 +0000

> The following changes since commit f878b995b0f746f5726af9e66940f3bf373dae91:
> 
>   Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next-2.6 (2011-02-15 12:25:19 -0800)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next-2.6.git for-davem
> 
> Add support for RFS acceleration in the sfc driver, and allow it to be
> enabled and disabled dynamically using ethtool.

Pulled, thanks Ben.

^ permalink raw reply

* Re: [PATCH 2/2] DM9000B: Fix PHY power for network down/up
From: David Miller @ 2011-02-22 18:24 UTC (permalink / raw)
  To: henry.nestler; +Cc: sshtylyov, netdev, tori, akpm, linux-arm-kernel
In-Reply-To: <4D62D323.7010403@henry.nestler.mail.gmail.com>

From: Henry Nestler <henry.nestler@gmail.com>
Date: Mon, 21 Feb 2011 22:03:31 +0100

> On 21.02.2011 12:14, Sergei Shtylyov wrote:
>> On 21-02-2011 0:45, Henry Nestler wrote:
>> 
>>> DM9000 revision B needs 1 ms delay after PHY power on (see spec), and PHY
>>> power must on in register
>> 
>>     Couldn't parse that.
> 
> This can read in manual DM900B-12-DS-F02 from September 2 2010, Page 14:
> "If this Register 1FH bit 0 is updated from '1' to '0', the all
> Registers can not be accessed within 1ms."
> 
> The example driver code waits 2 ms.
> 
>>> diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
>>> index 2d4c4fc..5925569 100644
>>> --- a/drivers/net/dm9000.c
>>> +++ b/drivers/net/dm9000.c
>> [...]
>>> @@ -1194,6 +1191,10 @@ dm9000_open(struct net_device *dev)
>>>   	if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
>>>   		return -EAGAIN;
>>>
>>> +	/* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
>>> +	iow(db, DM9000_GPR, 0);	/* REG_1F bit0 activate phyxcer */
>>> +	udelay(1000); /* delay needs by DM9000B */
>> 
>>     Why not mdelay(1)?
> 
> Because udelay is the base of mdelay.
> See include/linux/delay.h:31
> 
> #define mdelay(n) ... udelay((n)*1000)

He is telling you to use mdelay(1) because it's clearer.  Please do
so.

^ permalink raw reply

* Re: [PATCH net-next 0/6] be2net: patch series
From: David Miller @ 2011-02-22 18:27 UTC (permalink / raw)
  To: ajit.khaparde; +Cc: netdev
In-Reply-To: <20110220214242.GA13723@akhaparde-VBox>

From: Ajit Khaparde <ajit.khaparde@emulex.com>
Date: Sun, 20 Feb 2011 15:42:42 -0600

> Patch series for the be2net driver.
> 
> [1/6] be2net: add new counters to display via ethtool stats
> [2/6] be2net: fixes in ethtool selftest
> [3/6] be2net: variable name change
> [4/6] be2net: fix to ignore transparent vlan ids wrongly indicated by NIC
> [5/6] be2net: add code to display temperature of ASIC
> [6/6] be2net: use hba_port_num instead of port_num
> 
> Please Apply.

All applied, thanks.

^ permalink raw reply

* Re: [PATCH NEXT 1/2] qlcnic: fix type of module parameters
From: David Miller @ 2011-02-22 18:31 UTC (permalink / raw)
  To: amit.salecha; +Cc: netdev, ameen.rahman, anirban.chakraborty
In-Reply-To: <1298289514-15671-2-git-send-email-amit.salecha@qlogic.com>

From: Amit Kumar Salecha <amit.salecha@qlogic.com>
Date: Mon, 21 Feb 2011 03:58:33 -0800

> o Module parameters auto_fw_reset, use_msi, use_msi_x, qlcnic_mac_learn,
>   and load_fw_file should be of type bool not int.
> o All module parameters should have qlcnic prefix.
> o Remove unnecessary macro for value "1".
> 
> Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>

You must not change module parameter names on a whim, as this will
break scripts.

When you create a module parameter in your driver, you are creating
something users will use, and therefore an API.  You therefore
cannot change it without breaking stuff.

This is yet another reason I scream at anyone who adds module
parameters to network drivers, they are always "the wrong thing
to do".

None of these values you guys have module parameter for in the
qlcnic driver are providing facilities that are really qlcnic
specific at all.

MSI-X enablement, firmware loading controls, etc.  All of this
stuff is generic and would be potentially necessary in any device
driver, not just qlcnic's.

Therefore generic facilities are where this stuff should be
implemented, instead of in driver specific module parameters.

I will not apply these patches, sorry.

^ permalink raw reply

* Oops in cleanup_once - 2.6.37
From: Vlado Drzik @ 2011-02-22 18:09 UTC (permalink / raw)
  To: netdev

 Hello,

We are recently facing crashes with 2.6.36.1 and also 2.6.37 on our
routers/firewalls (on weekly basis).
Kernels are x86_64. We use igb and e1000e network cards and crashes are
not happening during the peek load (peak is 200kpps).

I have several crashdumps available if that could help someone.
It looks like iptables  might be somehow involved... (I always see
reject in there)

I've seen similar thing reported on kernel mailing list but no sadly
resolution. Could someone take a quick look?

Here is one of Oops messages (all look very similiar):
 
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
IP: [<ffffffff812e714a>] cleanup_once+0x4a/0x1f0
PGD 0
Oops: 0002 [#1] SMP
last sysfs file: /sys/kernel/kexec_crash_loaded
CPU 4
Modules linked in: act_mirred sch_ingress cls_u32 sch_htb ifb
nf_conntrack_netlink nfnetlink i2c_dev i2c_core bonding 8021q ipt_LOG
xt_comment ipt_REJECT xt_state ipt_REDIRECT x
t_tcpudp xt_CLASSIFY xt_mark iptable_raw ip_set_macipmap dm_mirror
dm_region_hash dm_log dm_mod video output hed battery ac ipt_set ip_set
xt_ACCOUNT compat_xtables nf_nat_ftp n
f_conntrack_ftp iptable_mangle iptable_nat nf_nat nf_conntrack_ipv4
nf_conntrack nf_defrag_ipv4 iptable_filter ip_tables x_tables sg sr_mod
cdrom e1000e bnx2 i5000_edac edac_cor
e igb psmouse serio_raw ata_piix libata shpchp pcspkr dcdbas usb_storage
megaraid_sas sd_mod scsi_mod ehci_hcd ohci_hcd uhci_hcd [last unloaded:
microcode]

Pid: 0, comm: kworker/0:1 Not tainted 2.6.37 #1 0UR033/PowerEdge 1950
RIP: 0010:[<ffffffff812e714a>]  [<ffffffff812e714a>] cleanup_once+0x4a/0x1f0
RSP: 0018:ffff8800cfd03710  EFLAGS: 00010206
RAX: ffff88012d49fcc0 RBX: ffff88012ccd6f58 RCX: 0000000000000013
RDX: 0000000000000000 RSI: 0000000000000013 RDI: ffffffff814c5810
RBP: 0000000000000000 R08: ffff88011d796000 R09: ffff88011c37b9c0
R10: 0000000000000014 R11: ffff88011d5bf340 R12: ffff88012ccd6f40
R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000040
FS:  0000000000000000(0000) GS:ffff8800cfd00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000008 CR3: 00000000b6550000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process kworker/0:1 (pid: 0, threadinfo ffff88012fd72000, task
ffff88012fd616c0)
Stack:
 ffff88012b5ac580 ffff88011330d402 ffffc900119111d0 ffffffffa01d677a
 ffff88011c12fe00 ffff88012c7ebb00 ffff88012fed4090 ffffffff8105b3ce
 ffff88012b5ac000 00008800cfd0dd08 ffff88012b5ac580 ffff88012c7ebb00
Call Trace:
 <IRQ>
 [<ffffffffa01d677a>] ? e1000_xmit_frame+0x98a/0xc90 [e1000e]
 [<ffffffff8105b3ce>] ? hrtimer_interrupt+0xfe/0x1f0
 [<ffffffff812b17e0>] ? skb_checksum+0x50/0x2d0
 [<ffffffff812bc6b8>] ? dev_hard_start_xmit+0x528/0x750
 [<ffffffff810de8c8>] ? __slab_alloc+0x1d8/0x2e0
 [<ffffffff812ae092>] ? sock_alloc_send_pskb+0x1a2/0x2f0
 [<ffffffff812375b5>] ? secure_ip_id+0x45/0x50
 [<ffffffff812e7502>] ? inet_getpeer+0xf2/0x1f0
 [<ffffffff813106f2>] ? icmp_glue_bits+0x82/0xa0
 [<ffffffff812eae36>] ? ip_append_data+0x896/0xb70
 [<ffffffff81310670>] ? icmp_glue_bits+0x0/0xa0
 [<ffffffff812e585f>] ? rt_bind_peer+0xf/0x40
 [<ffffffff812e597f>] ? __ip_select_ident+0xef/0x130
 [<ffffffff812ebebf>] ? ip_push_pending_frames+0x2ff/0x3c0
 [<ffffffff8131109e>] ? icmp_send+0x37e/0x630
 [<ffffffffa0160077>] ? igb_xmit_frame_ring_adv+0x617/0xc20 [igb]
 [<ffffffff81047214>] ? lock_timer_base+0x34/0x70
 [<ffffffff812bc6b8>] ? dev_hard_start_xmit+0x528/0x750
 [<ffffffffa017bb3d>] ? nf_ct_invert_tuple+0x6d/0x90 [nf_conntrack]
 [<ffffffffa02a232d>] ? reject_tg+0x2cd/0x3e0 [ipt_REJECT]
 [<ffffffffa0159bec>] ? ipt_do_table+0x34c/0x5d0 [ip_tables]
 [<ffffffff8131b084>] ? fib_validate_source+0x104/0x2c0
 [<ffffffff812e3fef>] ? rt_intern_hash+0x51f/0x5a0
 [<ffffffff812e0e7e>] ? nf_iterate+0x5e/0x90
 [<ffffffff812e7e70>] ? ip_local_deliver_finish+0x0/0x1f0
 [<ffffffff812e10e6>] ? nf_hook_slow+0x76/0xf0
 [<ffffffff812e7e70>] ? ip_local_deliver_finish+0x0/0x1f0
 [<ffffffff812e7e58>] ? ip_local_deliver+0x78/0x90
 [<ffffffff812ba68d>] ? __netif_receive_skb+0x3cd/0x5e0
 [<ffffffff812bec25>] ? process_backlog+0x85/0x160
 [<ffffffff812bee0d>] ? net_rx_action+0x10d/0x210
 [<ffffffff81040211>] ? __do_softirq+0xb1/0x1d0
 [<ffffffff810816b9>] ? handle_IRQ_event+0x49/0x150
 [<ffffffff81003b0c>] ? call_softirq+0x1c/0x30
 [<ffffffff8100503a>] ? do_softirq+0x4a/0x80
 [<ffffffff810045ba>] ? do_IRQ+0x6a/0xe0
 [<ffffffff81349b93>] ? ret_from_intr+0x0/0xa
 <EOI>
 [<ffffffff8100a34c>] ? mwait_idle+0x7c/0xd0
 [<ffffffff81001c12>] ? cpu_idle+0x42/0xb0
Code: 1d 00 48 81 fb 00 58 4c 81 0f 84 86 00 00 00 4c 8d 63 e8 48 8b 05
47 17 1f 00 41 2b 44 24 28 48 39 e8 72 71 48 8b 13 48 8b 43 08 <48> 89
42 08 48 89 10 48 89 5b 08 48 89 1
b f0 ff 43 14 48 c7 c7
RIP  [<ffffffff812e714a>] cleanup_once+0x4a/0x1f0
 RSP <ffff8800cfd03710>
CR2: 0000000000000008



^ permalink raw reply

* Re: [PATCH 0/9] ax88796: cleanups and convert to phylib and mdio_bitbang
From: David Miller @ 2011-02-22 19:18 UTC (permalink / raw)
  To: mkl; +Cc: netdev, ben, daniel
In-Reply-To: <1298293400-21570-1-git-send-email-mkl@pengutronix.de>

From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Mon, 21 Feb 2011 14:03:11 +0100

> this patch series fixes the phy-read/write problems of the ax88796
> (see http://www.spinics.net/lists/arm-kernel/msg98982.html).
> 
> Patches 1-8 clean verious aspects of the driver. The 9th patch replaces the
> handcrafted mdio bitbang loop with the generic mdio_bitbang driver.
> 
> This patch series has been tested on the Toradex colibri-320. With the patch
> mii-diag gives sound data:
> 
> root@grabowski:~ mii-diag
> Using the default interface 'eth0'.
> Basic registers of MII PHY #16:  3100 782d 003b 1841 01e1 45e1 0003 0000.
>  The autonegotiated capability is 01e0.
> The autonegotiated media type is 100baseTx-FD.
>  Basic mode control register 0x3100: Auto-negotiation enabled.
>  You have link beat, and everything is working OK.
>  Your link partner advertised 45e1: Flow-control 100baseTx-FD 100baseTx 10baseT-FD 10baseT, w/ 802.3X flow control.
>    End of basic transceiver information.
> 
> please review and consider to appply.

Pulled into net-next-2.6, thanks.

BTW, we could remove the ARM MIPS etc. dependencies this driver has,
and replace it with HAS_IOMEM, as all the interfaces the driver uses
should be provided by every architecture.

^ permalink raw reply

* Re: [PATCH] USB 10/100 RJ45 Ethernet Network Adapter
From: Sergei Shtylyov @ 2011-02-22 19:18 UTC (permalink / raw)
  To: Shahar Havivi
  Cc: linux-usb, linux-kernel, Peter Korsgaard, Greg Kroah-Hartman,
	netdev
In-Reply-To: <20110222140705.GA6055@redhat.com>

Hello.

Shahar Havivi wrote:

> The device is very similar to (0x0fe6, 0x8101),
> And works well with dm9601 driver.

   You should sign off your patch in order for it to be merged.

> ---
>  drivers/net/usb/dm9601.c |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)

> diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
> index 02b622e..2d1c8ae 100644
> --- a/drivers/net/usb/dm9601.c
> +++ b/drivers/net/usb/dm9601.c
> @@ -654,6 +654,11 @@ static const struct usb_device_id products[] = {
>  	 USB_DEVICE(0x0a46, 0x9000),	/* DM9000E */
>  	 .driver_info = (unsigned long)&dm9601_info,
>  	 },
> +	{
> +	 USB_DEVICE(0x0fe6, 0x9700),	/* DM9601 USB to Fast Ethernet Adapter */
> +

    Extra empty line shouldn't be here I guess...

> +	 .driver_info = (unsigned long)&dm9601_info,
> +	 },
>  	{},			// END
>  };

WBR, Sergei

^ permalink raw reply

* Re: [PATCH] USB 10/100 RJ45 Ethernet Network Adapter
From: David Miller @ 2011-02-22 19:24 UTC (permalink / raw)
  To: sshtylyov; +Cc: shaharh, linux-usb, linux-kernel, jacmet, gregkh, netdev
In-Reply-To: <4D640C0F.3050703@ru.mvista.com>

From: Sergei Shtylyov <sshtylyov@mvista.com>
Date: Tue, 22 Feb 2011 22:18:39 +0300

> Hello.
> 
> Shahar Havivi wrote:
> 
>> The device is very similar to (0x0fe6, 0x8101),
>> And works well with dm9601 driver.
> 
>   You should sign off your patch in order for it to be merged.

He did, see the follow-up patch with subject

[PATCH-v2] Added support for usb ethernet (0x0fe6, 0x9700)

^ permalink raw reply

* Re: [PATCH] rt2x00: Use ops name instead of device name
From: Ivo Van Doorn @ 2011-02-22 19:33 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Ben Hutchings, LKML, netdev, Felix Fietkau, John W. Linville,
	abogani
In-Reply-To: <1298382263.6140.1196.camel@gandalf.stny.rr.com>

Hi,

On Tue, Feb 22, 2011 at 2:44 PM, Steven Rostedt <rostedt@goodmis.org> wrote:
> On Tue, 2011-02-22 at 13:34 +0000, Ben Hutchings wrote:
>
>> > 19:   73474106          0   IO-APIC-fasteoi   ata_piix, uhci_hcd:usb6, 0000:05:01.0
>
>> >     rt2x00dev->irq = pci_dev->irq;
>> > -   rt2x00dev->name = pci_name(pci_dev);
>> > +   rt2x00dev->name = ops->name;
>
>
>> But then how can users distinguish the IRQs for multiple devices handled
>> by the same driver?  (Probably unusual for WLAN devices, but still
>> possible.)
>>
>> I assume you can't use a net device name as there may be multiple net
>> devices per bus device?
>
> Honestly, I do not know this code well enough, but this patch seemed to
> solve the problem at hand. Hence I sent it out to the experts hoping
> they either take this patch or come up with a proper solution ;)
>
> In any case, just posting the pci address is not a pretty answer.

I just checked the other wireless drivers, and they all seem to use
the modulename. So I guess your patch is correct. You can add my:

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

^ permalink raw reply

* pull request: wireless-2.6 2011-02-22
From: John W. Linville @ 2011-02-22 19:37 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

Dave,

Here is the latest round of wireless fixes intended for 2.6.38.
Included are a DMA API fix for p54, an ath5k channel setting fix
for AR2317 hardware, a WARNING fix related to conn_mon_timer, a lock
order fix in cfg80211_wext_siwfreq, a bluetooth locking fix, and a
few simple hardware-enablement patches.

There are a couple of other notables.  There is an ath9k patch that
reverts some earlier patches that cause a regression in power usage.
Also, there is a fairly large ath5k patch to address a regression
related to fast channel switching.  The patch seems bigger than it
really is because it moves some code around.  Both of these cite the
related bugzilla entry.

Please let me know if there are problems!

John

---

The following changes since commit c24f691b56107feeba076616982093ee2d3c8fb5:

  tcp: undo_retrans counter fixes (2011-02-21 11:31:18 -0800)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master

Cho, Yu-Chen (1):
      Bluetooth: Add Atheros BT AR5BBU12 fw supported

Christian Lamparter (1):
      p54pci: update receive dma buffers before and after processing

Daniel J Blueman (1):
      fix cfg80211_wext_siwfreq lock ordering...

Gertjan van Wingerde (1):
      rt2x00: Fix WPA TKIP Michael MIC failures.

John W. Linville (1):
      Merge branch 'master' of git://git.kernel.org/.../padovan/bluetooth-2.6

Mohammed Shafi Shajakhan (1):
      ath9k: Fix ath9k prevents CPU to enter C3 states

Nick Kossifidis (1):
      ath5k: Fix fast channel switching

Nikolay Ledovskikh (1):
      ath5k: Correct channel setting for AR2317 chip

Oliver Neukum (1):
      Bluetooth: fix crash with quirky dongles doing sound

Stanislaw Gruszka (1):
      mac80211: fix conn_mon_timer running after disassociate

Vladislav P (1):
      Bluetooth: Release BTM while sleeping to avoid deadlock

Xose Vazquez Perez (1):
      wireless: rt2x00: rt2800pci.c: add two ids

 drivers/bluetooth/ath3k.c               |    3 +
 drivers/bluetooth/btusb.c               |    7 +-
 drivers/net/wireless/ath/ath5k/phy.c    |  143 +++++++++++++++++++------------
 drivers/net/wireless/ath/ath9k/ath9k.h  |    6 --
 drivers/net/wireless/ath/ath9k/init.c   |    8 --
 drivers/net/wireless/ath/ath9k/main.c   |    8 --
 drivers/net/wireless/p54/p54pci.c       |   14 ++-
 drivers/net/wireless/rt2x00/rt2800pci.c |    8 ++
 drivers/net/wireless/rt2x00/rt2800usb.c |    6 ++
 net/bluetooth/rfcomm/tty.c              |    2 +
 net/mac80211/mlme.c                     |    6 ++
 net/wireless/wext-compat.c              |    4 +-
 12 files changed, 129 insertions(+), 86 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 333c212..6dcd55a 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -41,6 +41,9 @@ static struct usb_device_id ath3k_table[] = {
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03F0, 0x311D) },
+
+	/* Atheros AR5BBU12 with sflash firmware */
+	{ USB_DEVICE(0x0489, 0xE02C) },
 	{ }	/* Terminating entry */
 };
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 4cefa91..b7f2f37 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -105,6 +105,9 @@ static struct usb_device_id blacklist_table[] = {
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
 
+	/* Atheros AR5BBU12 with sflash firmware */
+	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
+
 	/* Broadcom BCM2035 */
 	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
 	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -829,7 +832,7 @@ static void btusb_work(struct work_struct *work)
 
 	if (hdev->conn_hash.sco_num > 0) {
 		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
-			err = usb_autopm_get_interface(data->isoc);
+			err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
 			if (err < 0) {
 				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 				usb_kill_anchored_urbs(&data->isoc_anchor);
@@ -858,7 +861,7 @@ static void btusb_work(struct work_struct *work)
 
 		__set_isoc_interface(hdev, 0);
 		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
-			usb_autopm_put_interface(data->isoc);
+			usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
 	}
 }
 
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 78c26fd..62ce2f4 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -282,6 +282,34 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah)
 	return 0;
 }
 
+/*
+ * Wait for synth to settle
+ */
+static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
+			struct ieee80211_channel *channel)
+{
+	/*
+	 * On 5211+ read activation -> rx delay
+	 * and use it (100ns steps).
+	 */
+	if (ah->ah_version != AR5K_AR5210) {
+		u32 delay;
+		delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+			AR5K_PHY_RX_DELAY_M;
+		delay = (channel->hw_value & CHANNEL_CCK) ?
+			((delay << 2) / 22) : (delay / 10);
+		if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
+			delay = delay << 1;
+		if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
+			delay = delay << 2;
+		/* XXX: /2 on turbo ? Let's be safe
+		 * for now */
+		udelay(100 + delay);
+	} else {
+		mdelay(1);
+	}
+}
+
 
 /**********************\
 * RF Gain optimization *
@@ -1253,6 +1281,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
 	case AR5K_RF5111:
 		ret = ath5k_hw_rf5111_channel(ah, channel);
 		break;
+	case AR5K_RF2317:
 	case AR5K_RF2425:
 		ret = ath5k_hw_rf2425_channel(ah, channel);
 		break;
@@ -3237,6 +3266,13 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 		/* Failed */
 		if (i >= 100)
 			return -EIO;
+
+		/* Set channel and wait for synth */
+		ret = ath5k_hw_channel(ah, channel);
+		if (ret)
+			return ret;
+
+		ath5k_hw_wait_for_synth(ah, channel);
 	}
 
 	/*
@@ -3251,13 +3287,53 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 	if (ret)
 		return ret;
 
+	/* Write OFDM timings on 5212*/
+	if (ah->ah_version == AR5K_AR5212 &&
+		channel->hw_value & CHANNEL_OFDM) {
+
+		ret = ath5k_hw_write_ofdm_timings(ah, channel);
+		if (ret)
+			return ret;
+
+		/* Spur info is available only from EEPROM versions
+		 * greater than 5.3, but the EEPROM routines will use
+		 * static values for older versions */
+		if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
+			ath5k_hw_set_spur_mitigation_filter(ah,
+							    channel);
+	}
+
+	/* If we used fast channel switching
+	 * we are done, release RF bus and
+	 * fire up NF calibration.
+	 *
+	 * Note: Only NF calibration due to
+	 * channel change, not AGC calibration
+	 * since AGC is still running !
+	 */
+	if (fast) {
+		/*
+		 * Release RF Bus grant
+		 */
+		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
+				    AR5K_PHY_RFBUS_REQ_REQUEST);
+
+		/*
+		 * Start NF calibration
+		 */
+		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+					AR5K_PHY_AGCCTL_NF);
+
+		return ret;
+	}
+
 	/*
 	 * For 5210 we do all initialization using
 	 * initvals, so we don't have to modify
 	 * any settings (5210 also only supports
 	 * a/aturbo modes)
 	 */
-	if ((ah->ah_version != AR5K_AR5210) && !fast) {
+	if (ah->ah_version != AR5K_AR5210) {
 
 		/*
 		 * Write initial RF gain settings
@@ -3276,22 +3352,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 		if (ret)
 			return ret;
 
-		/* Write OFDM timings on 5212*/
-		if (ah->ah_version == AR5K_AR5212 &&
-			channel->hw_value & CHANNEL_OFDM) {
-
-			ret = ath5k_hw_write_ofdm_timings(ah, channel);
-			if (ret)
-				return ret;
-
-			/* Spur info is available only from EEPROM versions
-			 * greater than 5.3, but the EEPROM routines will use
-			 * static values for older versions */
-			if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
-				ath5k_hw_set_spur_mitigation_filter(ah,
-								    channel);
-		}
-
 		/*Enable/disable 802.11b mode on 5111
 		(enable 2111 frequency converter + CCK)*/
 		if (ah->ah_radio == AR5K_RF5111) {
@@ -3322,47 +3382,20 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 	 */
 	ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
 
+	ath5k_hw_wait_for_synth(ah, channel);
+
 	/*
-	 * On 5211+ read activation -> rx delay
-	 * and use it.
+	 * Perform ADC test to see if baseband is ready
+	 * Set tx hold and check adc test register
 	 */
-	if (ah->ah_version != AR5K_AR5210) {
-		u32 delay;
-		delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
-			AR5K_PHY_RX_DELAY_M;
-		delay = (channel->hw_value & CHANNEL_CCK) ?
-			((delay << 2) / 22) : (delay / 10);
-		if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
-			delay = delay << 1;
-		if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
-			delay = delay << 2;
-		/* XXX: /2 on turbo ? Let's be safe
-		 * for now */
-		udelay(100 + delay);
-	} else {
-		mdelay(1);
-	}
-
-	if (fast)
-		/*
-		 * Release RF Bus grant
-		 */
-		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
-				    AR5K_PHY_RFBUS_REQ_REQUEST);
-	else {
-		/*
-		 * Perform ADC test to see if baseband is ready
-		 * Set tx hold and check adc test register
-		 */
-		phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
-		ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
-		for (i = 0; i <= 20; i++) {
-			if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
-				break;
-			udelay(200);
-		}
-		ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
+	phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+	ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
+	for (i = 0; i <= 20; i++) {
+		if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
+			break;
+		udelay(200);
 	}
+	ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
 
 	/*
 	 * Start automatic gain control calibration
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 23838e3..1a7fa6e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -21,7 +21,6 @@
 #include <linux/device.h>
 #include <linux/leds.h>
 #include <linux/completion.h>
-#include <linux/pm_qos_params.h>
 
 #include "debug.h"
 #include "common.h"
@@ -57,8 +56,6 @@ struct ath_node;
 
 #define A_MAX(a, b) ((a) > (b) ? (a) : (b))
 
-#define ATH9K_PM_QOS_DEFAULT_VALUE	55
-
 #define TSF_TO_TU(_h,_l) \
 	((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
 
@@ -633,8 +630,6 @@ struct ath_softc {
 	struct ath_descdma txsdma;
 
 	struct ath_ant_comb ant_comb;
-
-	struct pm_qos_request_list pm_qos_req;
 };
 
 struct ath_wiphy {
@@ -666,7 +661,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 extern struct ieee80211_ops ath9k_ops;
 extern int ath9k_modparam_nohwcrypt;
 extern int led_blink;
-extern int ath9k_pm_qos_value;
 extern bool is_ath9k_unloaded;
 
 irqreturn_t ath_isr(int irq, void *dev);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 087a6a9..a033d01 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -41,10 +41,6 @@ static int ath9k_btcoex_enable;
 module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
 MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
 
-int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
-module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
-MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
-
 bool is_ath9k_unloaded;
 /* We use the hw_value as an index into our private channel structure */
 
@@ -762,9 +758,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
 	ath_init_leds(sc);
 	ath_start_rfkill_poll(sc);
 
-	pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
-			   PM_QOS_DEFAULT_VALUE);
-
 	return 0;
 
 error_world:
@@ -831,7 +824,6 @@ void ath9k_deinit_device(struct ath_softc *sc)
 	}
 
 	ieee80211_unregister_hw(hw);
-	pm_qos_remove_request(&sc->pm_qos_req);
 	ath_rx_cleanup(sc);
 	ath_tx_cleanup(sc);
 	ath9k_deinit_softc(sc);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index da5c645..a09d15f 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1173,12 +1173,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
 			ath9k_btcoex_timer_resume(sc);
 	}
 
-	/* User has the option to provide pm-qos value as a module
-	 * parameter rather than using the default value of
-	 * 'ATH9K_PM_QOS_DEFAULT_VALUE'.
-	 */
-	pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value);
-
 	if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
 		common->bus_ops->extn_synch_en(common);
 
@@ -1345,8 +1339,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
 	sc->sc_flags |= SC_OP_INVALID;
 
-	pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
-
 	mutex_unlock(&sc->mutex);
 
 	ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 1eacba4..0494d7b 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -199,6 +199,7 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
 	while (i != idx) {
 		u16 len;
 		struct sk_buff *skb;
+		dma_addr_t dma_addr;
 		desc = &ring[i];
 		len = le16_to_cpu(desc->len);
 		skb = rx_buf[i];
@@ -216,17 +217,20 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
 
 			len = priv->common.rx_mtu;
 		}
+		dma_addr = le32_to_cpu(desc->host_addr);
+		pci_dma_sync_single_for_cpu(priv->pdev, dma_addr,
+			priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
 		skb_put(skb, len);
 
 		if (p54_rx(dev, skb)) {
-			pci_unmap_single(priv->pdev,
-					 le32_to_cpu(desc->host_addr),
-					 priv->common.rx_mtu + 32,
-					 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(priv->pdev, dma_addr,
+				priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
 			rx_buf[i] = NULL;
-			desc->host_addr = 0;
+			desc->host_addr = cpu_to_le32(0);
 		} else {
 			skb_trim(skb, 0);
+			pci_dma_sync_single_for_device(priv->pdev, dma_addr,
+				priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
 			desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
 		}
 
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index aa97971..3b3f1e4 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -652,6 +652,12 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
 		 */
 		rxdesc->flags |= RX_FLAG_IV_STRIPPED;
 
+		/*
+		 * The hardware has already checked the Michael Mic and has
+		 * stripped it from the frame. Signal this to mac80211.
+		 */
+		rxdesc->flags |= RX_FLAG_MMIC_STRIPPED;
+
 		if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
 			rxdesc->flags |= RX_FLAG_DECRYPTED;
 		else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
@@ -1065,6 +1071,8 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
 	{ PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
 #endif
 #ifdef CONFIG_RT2800PCI_RT35XX
+	{ PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
 	{ PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index b97a4a5..197a36c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -486,6 +486,12 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 		 */
 		rxdesc->flags |= RX_FLAG_IV_STRIPPED;
 
+		/*
+		 * The hardware has already checked the Michael Mic and has
+		 * stripped it from the frame. Signal this to mac80211.
+		 */
+		rxdesc->flags |= RX_FLAG_MMIC_STRIPPED;
+
 		if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
 			rxdesc->flags |= RX_FLAG_DECRYPTED;
 		else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 2575c2d..d7b9af4 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -727,7 +727,9 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 			break;
 		}
 
+		tty_unlock();
 		schedule();
+		tty_lock();
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&dev->wait, &wait);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 45fbb9e..c9ceb4d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1033,6 +1033,12 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
 	if (is_multicast_ether_addr(hdr->addr1))
 		return;
 
+	/*
+	 * In case we receive frames after disassociation.
+	 */
+	if (!sdata->u.mgd.associated)
+		return;
+
 	ieee80211_sta_reset_conn_monitor(sdata);
 }
 
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 3e5dbd4..d112f03 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -802,11 +802,11 @@ int cfg80211_wext_siwfreq(struct net_device *dev,
 			return freq;
 		if (freq == 0)
 			return -EINVAL;
-		wdev_lock(wdev);
 		mutex_lock(&rdev->devlist_mtx);
+		wdev_lock(wdev);
 		err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
-		mutex_unlock(&rdev->devlist_mtx);
 		wdev_unlock(wdev);
+		mutex_unlock(&rdev->devlist_mtx);
 		return err;
 	default:
 		return -EOPNOTSUPP;
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply related

* Re: [PATCH] rt2x00: Use ops name instead of device name
From: John W. Linville @ 2011-02-22 19:47 UTC (permalink / raw)
  To: Ivo Van Doorn
  Cc: Steven Rostedt, Ben Hutchings, LKML, netdev, Felix Fietkau,
	abogani
In-Reply-To: <AANLkTinNUnq7JQDpTzCv24A7T7fMn9iPFisQEBZGkELr@mail.gmail.com>

On Tue, Feb 22, 2011 at 08:33:45PM +0100, Ivo Van Doorn wrote:
> Hi,
> 
> On Tue, Feb 22, 2011 at 2:44 PM, Steven Rostedt <rostedt@goodmis.org> wrote:
> > On Tue, 2011-02-22 at 13:34 +0000, Ben Hutchings wrote:
> >
> >> > 19:   73474106          0   IO-APIC-fasteoi   ata_piix, uhci_hcd:usb6, 0000:05:01.0
> >
> >> >     rt2x00dev->irq = pci_dev->irq;
> >> > -   rt2x00dev->name = pci_name(pci_dev);
> >> > +   rt2x00dev->name = ops->name;
> >
> >
> >> But then how can users distinguish the IRQs for multiple devices handled
> >> by the same driver?  (Probably unusual for WLAN devices, but still
> >> possible.)
> >>
> >> I assume you can't use a net device name as there may be multiple net
> >> devices per bus device?
> >
> > Honestly, I do not know this code well enough, but this patch seemed to
> > solve the problem at hand. Hence I sent it out to the experts hoping
> > they either take this patch or come up with a proper solution ;)
> >
> > In any case, just posting the pci address is not a pretty answer.
> 
> I just checked the other wireless drivers, and they all seem to use
> the modulename. So I guess your patch is correct. You can add my:
> 
> Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

I completely missed this series -- please be sure to Cc:
linux-wireless@vger.kernel.org if you resend, and/or resend the series
directly to me?

Thanks!

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH] rt2x00: Use ops name instead of device name
From: Steven Rostedt @ 2011-02-22 19:52 UTC (permalink / raw)
  To: Ivo Van Doorn
  Cc: Ben Hutchings, LKML, netdev, Felix Fietkau, John W. Linville,
	abogani
In-Reply-To: <AANLkTinNUnq7JQDpTzCv24A7T7fMn9iPFisQEBZGkELr@mail.gmail.com>

On Tue, 2011-02-22 at 20:33 +0100, Ivo Van Doorn wrote:
> Hi,
> 
> On Tue, Feb 22, 2011 at 2:44 PM, Steven Rostedt <rostedt@goodmis.org> wrote:
> > On Tue, 2011-02-22 at 13:34 +0000, Ben Hutchings wrote:
> >
> >> > 19:   73474106          0   IO-APIC-fasteoi   ata_piix, uhci_hcd:usb6, 0000:05:01.0
> >
> >> >     rt2x00dev->irq = pci_dev->irq;
> >> > -   rt2x00dev->name = pci_name(pci_dev);
> >> > +   rt2x00dev->name = ops->name;
> >
> >
> >> But then how can users distinguish the IRQs for multiple devices handled
> >> by the same driver?  (Probably unusual for WLAN devices, but still
> >> possible.)
> >>
> >> I assume you can't use a net device name as there may be multiple net
> >> devices per bus device?
> >
> > Honestly, I do not know this code well enough, but this patch seemed to
> > solve the problem at hand. Hence I sent it out to the experts hoping
> > they either take this patch or come up with a proper solution ;)
> >
> > In any case, just posting the pci address is not a pretty answer.
> 
> I just checked the other wireless drivers, and they all seem to use
> the modulename. So I guess your patch is correct. You can add my:
> 
> Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

Thanks!

Actually, to answer Ben's question. lspci should give you what you want.

On my local box (not the one mentioned above):

$ lspci -vv
[...]
00:0a.0 Bridge: nVidia Corporation CK804 Ethernet Controller (rev a3)
        Subsystem: Tyan Computer Tomcat K8E (S2865)
        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+
        Latency: 0 (250ns min, 5000ns max)

        Interrupt: pin A routed to IRQ 23

        Region 0: Memory at febf9000 (32-bit, non-prefetchable) [size=4K]
        Region 1: I/O ports at b400 [size=8]
        Capabilities: <access denied>
        Kernel driver in use: forcedeth


(spaces added by me)

$ cat /proc/interrupts
[...]
 23:        547     648564   IO-APIC-fasteoi   ohci_hcd:usb2, eth0


-- Steve

^ permalink raw reply

* Re: pull request: wireless-2.6 2011-02-22
From: David Miller @ 2011-02-22 19:55 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20110222193757.GF12153@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Tue, 22 Feb 2011 14:37:57 -0500

> Here is the latest round of wireless fixes intended for 2.6.38.
> Included are a DMA API fix for p54, an ath5k channel setting fix
> for AR2317 hardware, a WARNING fix related to conn_mon_timer, a lock
> order fix in cfg80211_wext_siwfreq, a bluetooth locking fix, and a
> few simple hardware-enablement patches.
> 
> There are a couple of other notables.  There is an ath9k patch that
> reverts some earlier patches that cause a regression in power usage.
> Also, there is a fairly large ath5k patch to address a regression
> related to fast channel switching.  The patch seems bigger than it
> really is because it moves some code around.  Both of these cite the
> related bugzilla entry.
> 
> Please let me know if there are problems!

Pulled, thanks a lot John.

^ permalink raw reply

* Re: [PATCH 2/2] DM9000B: Fix PHY power for network down/up
From: Henry Nestler @ 2011-02-22 19:58 UTC (permalink / raw)
  To: David Miller; +Cc: sshtylyov, netdev, linux-arm-kernel, Sergei Shtylyov
In-Reply-To: <20110222.102410.260079835.davem@davemloft.net>

Hello David,

On 22.02.2011 19:24, David Miller wrote:
> From: Henry Nestler <henry.nestler@gmail.com>
> Date: Mon, 21 Feb 2011 22:03:31 +0100
> 
>> On 21.02.2011 12:14, Sergei Shtylyov wrote:
>>> On 21-02-2011 0:45, Henry Nestler wrote:
>>>> +	udelay(1000); /* delay needs by DM9000B */
>>>
>>>     Why not mdelay(1)?
>>
>> Because udelay is the base of mdelay.
>> See include/linux/delay.h:31
>>
>> #define mdelay(n) ... udelay((n)*1000)
> 
> He is telling you to use mdelay(1) because it's clearer.  Please do
> so.

Thanks, that text explains it better. No problem. I will resend this patch.

-- 
Henry N.

^ permalink raw reply

* Re: [stable] 2.6.38-rc5-git6: Reported regressions 2.6.36 -> 2.6.37
From: Greg KH @ 2011-02-22 20:07 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux SCSI List, Florian Mickler, Network Development,
	Linux Wireless List, Linux Kernel Mailing List, DRI, Linux ACPI,
	Andrew Morton, Kernel Testers List, Linus Torvalds, Linux PM List,
	Maciej Rutecki
In-Reply-To: <JwKd6rET8XO.A._ZC.gbuYNB@chimera>

On Mon, Feb 21, 2011 at 11:29:26PM +0100, Rafael J. Wysocki wrote:
> Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=24582
> Subject		: Kernel Oops at tty_buffer_request_room when using pppd program (2.6.37-rc4)
> Submitter	: baoyb <baoyb@avit.org.cn>
> Date		: 2010-12-08 13:55 (76 days old)
> Message-ID	: <EF6DDE218DB34702B1FA84D6CD7EA771@baoyb>
> References	: http://marc.info/?l=linux-kernel&m=129181763525738&w=2
> Handled-By	: Jiri Slaby <jslaby@suse.cz>
> Patch		: https://bugzilla.kernel.org/attachment.cgi?id=47872

This is queued up already for sending to Linus soon.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH] USB 10/100 RJ45 Ethernet Network Adapter
From: Sergei Shtylyov @ 2011-02-22 20:18 UTC (permalink / raw)
  To: David Miller
  Cc: sshtylyov, shaharh, linux-usb, linux-kernel, jacmet, gregkh,
	netdev
In-Reply-To: <20110222.112403.179931392.davem@davemloft.net>

Hello.

David Miller wrote:

>> Shahar Havivi wrote:

>>> The device is very similar to (0x0fe6, 0x8101),
>>> And works well with dm9601 driver.
>>   You should sign off your patch in order for it to be merged.

> He did, see the follow-up patch with subject

> [PATCH-v2] Added support for usb ethernet (0x0fe6, 0x9700)

    Yeah, I've somewhat hasted with following up.

WBR, Sergei

^ permalink raw reply

* [PATCH] ax88796: depend on HAS_IOMEM not on individual ARCHs
From: Marc Kleine-Budde @ 2011-02-22 20:19 UTC (permalink / raw)
  To: netdev; +Cc: davem, Marc Kleine-Budde
In-Reply-To: <20110222.111856.102538007.davem@davemloft.net>

Reported-by: David Miller <davem@davemloft.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---

Hello David,

this patch is available in the git repository at:
  git://git.pengutronix.de/git/mkl/linux-2.6.git net/ax88796

based on the patches already merged into net-next.

regards, Marc

 drivers/net/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f4b3927..5d7d9e7 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -237,7 +237,7 @@ source "drivers/net/arm/Kconfig"
 
 config AX88796
 	tristate "ASIX AX88796 NE2000 clone support"
-	depends on ARM || MIPS || SUPERH
+	depends on HAS_IOMEM
 	select PHYLIB
 	select MDIO_BITBANG
 	help
-- 
1.7.2.3


^ permalink raw reply related

* [PATCH] sis900: use pci_dev->revision
From: Sergei Shtylyov @ 2011-02-22 20:29 UTC (permalink / raw)
  To: netdev, venza

This driver uses PCI_CLASS_REVISION instead of PCI_REVISION_ID, so it wasn't
converted by commit 44c10138fd4bbc4b6d6bff0873c24902f2a9da65 (PCI: Change all
drivers to use pci_device->revision).

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>

---
The patch is against the recent Linus' tree.

 drivers/net/sis900.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-2.6/drivers/net/sis900.c
===================================================================
--- linux-2.6.orig/drivers/net/sis900.c
+++ linux-2.6/drivers/net/sis900.c
@@ -495,7 +495,7 @@ static int __devinit sis900_probe(struct
 	sis_priv->mii_info.reg_num_mask = 0x1f;
 
 	/* Get Mac address according to the chip revision */
-	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev));
+	sis_priv->chipset_rev = pci_dev->revision;
 	if(netif_msg_probe(sis_priv))
 		printk(KERN_DEBUG "%s: detected revision %2.2x, "
 				"trying to get MAC address...\n",
@@ -532,7 +532,7 @@ static int __devinit sis900_probe(struct
 	/* save our host bridge revision */
 	dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL);
 	if (dev) {
-		pci_read_config_byte(dev, PCI_CLASS_REVISION, &sis_priv->host_bridge_rev);
+		sis_priv->host_bridge_rev = dev->revision;
 		pci_dev_put(dev);
 	}
 

^ permalink raw reply

* Re: [PATCH] ax88796: depend on HAS_IOMEM not on individual ARCHs
From: David Miller @ 2011-02-22 20:37 UTC (permalink / raw)
  To: mkl; +Cc: netdev
In-Reply-To: <1298405998-6214-1-git-send-email-mkl@pengutronix.de>

From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Tue, 22 Feb 2011 21:19:58 +0100

> Reported-by: David Miller <davem@davemloft.net>
> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> ---
> 
> Hello David,
> 
> this patch is available in the git repository at:
>   git://git.pengutronix.de/git/mkl/linux-2.6.git net/ax88796
> 
> based on the patches already merged into net-next.

I would like you to actually build test this.

I know it's going to cause allmodconfig build errors on sparc64,
for example.

^ permalink raw reply

* Re: [ethtool PATCH 2/2] Add RX packet classification interface
From: Alexander Duyck @ 2011-02-22 20:52 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Santwona Behera, netdev@vger.kernel.org
In-Reply-To: <1298302841.2608.35.camel@bwh-desktop>

I've included my response to your comments below.

Thanks,

Alex

On 2/21/2011 7:40 AM, Ben Hutchings wrote:
> On Thu, 2011-02-10 at 17:18 -0800, Alexander Duyck wrote:
>> From: Santwona Behera<santwona.behera@sun.com>
>>
>> This patch was originally introduced as:
>>    [PATCH 1/3] [ethtool] Add rx pkt classification interface
>>    Signed-off-by: Santwona Behera<santwona.behera@sun.com>
>>    http://patchwork.ozlabs.org/patch/23223/
>>
>> I have updated it to address a number of issues.  As a result I removed the
>> local caching of rules due to the fact that there were memory leaks in this
>> code and the rule manager would consume over 1Mb of space for an 8K table
>> when all that was needed was 1K in order to store which rules were active
>> and which were not.
>>
>> In addition I dropped the use of regions as there were multiple issue found
>> including the fact that the regions were not properly expanding beyond 2
>> and the fact that the regions required reading all of the rules in order to
>> correctly expand beyond 2.  By dropping the regions from the rule manager
>> it is possible to write a much cleaner interface leaving region management
>> to be done by either the driver or by external management scripts.
>>
>> I also added an ethtool bitops interface to allow for simple bit set and
>> test activities since the rule manager can most efficiently store the list
>> of active rules via a bitmap.
> [...]
>> diff --git a/ethtool-bitops.h b/ethtool-bitops.h
>> new file mode 100644
>> index 0000000..7101056
>> --- /dev/null
>> +++ b/ethtool-bitops.h
>> @@ -0,0 +1,25 @@
>> +#ifndef ETHTOOL_BITOPS_H__
>> +#define ETHTOOL_BITOPS_H__
>> +
>> +#define BITS_PER_LONG                __WORDSIZE
>
> This seems to be a glibc-internal macro and I don't think we should use
> it.
>
>> +#define BITS_PER_BYTE                8
>> +#define DIV_ROUND_UP(n, d)   (((n) + (d) - 1) / (d))
>> +#define BITS_TO_LONGS(nr)    DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
>
> In fact I notice you don't use it here...

Yeah, as I recall I don't think I trusted that definition of 
BITS_PER_LONG all that much anyway.  I will replace it with 
BITS_PER_BYTE * sizeof(long).

>> +static inline void set_bit(int nr, unsigned long *addr)
>> +{
>> +     addr[nr / BITS_PER_LONG] |= 1UL<<  (nr % BITS_PER_LONG);
>> +}
>> +
>> +static inline void clear_bit(int nr, unsigned long *addr)
>> +{
>> +     addr[nr / BITS_PER_LONG]&= ~(1UL<<  (nr % BITS_PER_LONG));
>> +}
>> +
>> +static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
>> +{
>> +     return ((1UL<<  (nr % BITS_PER_LONG))&
>> +             (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0UL;
>> +}
>> +
>> +#endif
>> diff --git a/ethtool-util.h b/ethtool-util.h
>> index f053028..e9300e2 100644
>> --- a/ethtool-util.h
>> +++ b/ethtool-util.h
>> @@ -103,4 +103,17 @@ int sfc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
>>   int st_mac100_dump_regs(struct ethtool_drvinfo *info,
>>                        struct ethtool_regs *regs);
>>   int st_gmac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
>> +
>> +/* Rx flow classification */
>> +#include<sys/ioctl.h>
>> +#include<net/if.h>
>
> Put #includes at the top of the file, please.

That will be updated in the next patch.

>> +int rxclass_parse_ruleopts(char **optstr, int opt_cnt,
>> +                        struct ethtool_rx_flow_spec *fsp, __u8 *loc_valid);
>> +int rxclass_rule_getall(int fd, struct ifreq *ifr);
>> +int rxclass_rule_get(int fd, struct ifreq *ifr, __u32 loc);
>> +int rxclass_rule_ins(int fd, struct ifreq *ifr,
>> +                  struct ethtool_rx_flow_spec *fsp, __u8 loc_valid);
>> +int rxclass_rule_del(int fd, struct ifreq *ifr, __u32 loc);
>> +
>>   #endif
>> diff --git a/ethtool.8.in b/ethtool.8.in
>> index 133825b..c183a3d 100644
>> --- a/ethtool.8.in
>> +++ b/ethtool.8.in
>> @@ -40,21 +40,36 @@
>>   [\\fB\\$1\\fP\ \\fIN\\fP]
>>   ..
>>   .\"
>> +.\"  .BM - same as above but has a mask field for format "[value N [m N]]"
>> +.\"
>> +.de BM
>> +[\\fB\\$1\\fP\ \\fIN\\fP\ [\\fBm\\fP\ \\fIN\\fP]]
>> +..
>> +.\"
>>   .\"  \(*MA - mac address
>>   .\"
>>   .ds MA \fIxx\fP\fB:\fP\fIyy\fP\fB:\fP\fIzz\fP\fB:\fP\fIaa\fP\fB:\fP\fIbb\fP\fB:\fP\fIcc\fP
>>   .\"
>> +.\"  \(*PA - IP address
>> +.\"
>> +.ds PA \fIx\fP\fB.\fP\fIx\fP\fB.\fP\fIx\fP\fB.\fP\fIx\fP
>> +.\"
>>   .\"  \(*WO - wol flags
>>   .\"
>>   .ds WO \fBp\fP|\fBu\fP|\fBm\fP|\fBb\fP|\fBa\fP|\fBg\fP|\fBs\fP|\fBd\fP...
>>   .\"
>>   .\"  \(*FL - flow type values
>>   .\"
>> -.ds FL \fBtcp4\fP|\fBudp4\fP|\fBah4\fP|\fBsctp4\fP|\fBtcp6\fP|\fBudp6\fP|\fBah6\fP|\fBsctp6\fP
>> +.ds FL \fBtcp4\fP|\fBudp4\fP|\fBah4\fP||\fBesp4\fP|\fBsctp4\fP|\fBtcp6\fP|\fBudp6\fP|\fBah6\fP|\fBesp6\fP|\fBsctp6\fP
>
> This adds two '|' characters between 'ah4' and 'esp4'.

I'll have this fixed for the next patch.

>>   .\"
>>   .\"  \(*HO - hash options
>>   .\"
>>   .ds HO \fBm\fP|\fBv\fP|\fBt\fP|\fBs\fP|\fBd\fP|\fBf\fP|\fBn\fP|\fBr\fP...
>> +.\"
>> +.\"  \(*L4 - L4 proto options
>> +.\"
>> +.ds L4 \fBtcp\fP|\fBudp\fP|\fBsctp\fP|\fBah\fP|\fBesp\fP|\fIN\fP
>> +.\"
>>   .\" Start URL.
>>   .de UR
>>   .  ds m1 \\$1\"
>> @@ -224,11 +239,27 @@ ethtool \- query or control network driver and hardware settings
>>   .B ethtool \-n
>>   .I ethX
>>   .RB [ rx-flow-hash \ \*(FL]
>> +.RB [ rx-rings ]
>> +.RB [ rx-class-rule-all ]
>> +.RB [ rx-class-rule
>> +.IR N ]
>
> Should use '.BN'.

It'll be in the next patch.

> [...]
>> diff --git a/ethtool.c b/ethtool.c
>> index 1afdfe4..b624980 100644
>> --- a/ethtool.c
>> +++ b/ethtool.c
>> @@ -6,6 +6,7 @@
>>    * Kernel 2.4 update Copyright 2001 Jeff Garzik<jgarzik@mandrakesoft.com>
>>    * Wake-on-LAN,natsemi,misc support by Tim Hockin<thockin@sun.com>
>>    * Portions Copyright 2002 Intel
>> + * Portions Copyright (C) Sun Microsystems 2008
>>    * do_test support by Eli Kupermann<eli.kupermann@intel.com>
>>    * ETHTOOL_PHYS_ID support by Chris Leech<christopher.leech@intel.com>
>>    * e1000 support by Scott Feldman<scott.feldman@intel.com>
>> @@ -14,6 +15,7 @@
>>    * amd8111e support by Reeja John<reeja.john@amd.com>
>>    * long arguments by Andi Kleen.
>>    * SMSC LAN911x support by Steve Glendinning<steve.glendinning@smsc.com>
>> + * Rx Network Flow Control configuration support<santwona.behera@sun.com>
>>    * Various features by Ben Hutchings<bhutchings@solarflare.com>;
>>    *   Copyright 2009, 2010 Solarflare Communications
>>    *
>> @@ -32,7 +34,7 @@
>>   #include<sys/ioctl.h>
>>   #include<sys/stat.h>
>>   #include<stdio.h>
>> -#include<string.h>
>> +#include<strings.h>
>
> No,<string.h>  is standard.

That's fine.  The original patch included this so I just carried it 
forward.  However there are two includes of string.h in this file so 
odds are the second one can just be dropped then.

> [...]
>> @@ -408,6 +425,14 @@ static int msglvl_changed;
>>   static u32 msglvl_wanted = 0;
>>   static u32 msglvl_mask = 0;
>>
>> +static int rx_rings_get = 0;
>> +static int rx_class_rule_get = -1;
>> +static int rx_class_rule_getall = 0;
>> +static int rx_class_rule_del = -1;
>> +static int rx_class_rule_added = 0;
>> +static struct ethtool_rx_flow_spec rx_rule_fs;
>> +static u8 rxclass_loc_valid = 0;
>> +
>>   static enum {
>>        ONLINE=0,
>>        OFFLINE,
> [...]
>> @@ -945,6 +974,23 @@ static void parse_cmdline(int argc, char **argp)
>>                                                rxflow_str_to_type(argp[i]);
>>                                        if (!rx_fhash_get)
>>                                                show_usage(1);
>> +                             } else if (!strcmp(argp[i], "rx-rings")) {
>> +                                     i += 1;
>> +                                     rx_rings_get = 1;
>
> I'm not convinced of the value of a separate rx-rings option/keyword.
> However it's probably worth displaying the number of rings/queues when
> showing other flow hashing and steering/filtering information (the -x
> option does this).

My thought was that it would be useful for determining the number of 
rings prior to adding a rule.  Especially if we have any kind of scripts 
running on top of ethtool so that we can avoid rules that will fail due 
to ring values being greater than the actual number of rings.  I might 
try looking into adding it to the display options for the filters.

>> +                             } else if (!strcmp(argp[i],
>> +                                                "rx-class-rule-all")) {
>> +                                     i += 1;
>> +                                     rx_class_rule_getall = 1;
>> +                             } else if (!strcmp(argp[i], "rx-class-rule")) {
>> +                                     i += 1;
>> +                                     if (i>= argc) {
>> +                                             show_usage(1);
>> +                                             break;
>> +                                     }
>> +                                     rx_class_rule_get =
>> +                                             strtol(argp[i], NULL, 0);
>> +                                     if (rx_class_rule_get<  0)
>> +                                             show_usage(1);
>
> Use get_uint_range(argp[i], 0, INT_MAX).

It'll be in the next patch.

>>                                } else
>>                                        show_usage(1);
>>                                break;
>
> I don't think the same options (-n, -N) should be used both for flow
> hashing and n-tuple flow steering/filtering.  This command-line
> interface and the structure used in the ethtool API just seem to reflect
> the implementation in the niu driver.
>
> (In fact I would much prefer it if the -u and -U options could be used
> for both the rxnfc and rxntuple interfaces.  But I haven't thought about
> how the differences in functionality would be exposed to or hidden from
> the user.)

I was kind of thinking about merging the two interfaces too, but I was 
looking at it more from the perspective of moving away from ntuple more 
towards this newer interface.  My main motivation being that the filter 
display option is so badly broken for ntuple that it would be easier to 
make ntuple a subset of the flow classifier instead of the other way around.

What would you think of using the "flow-type" keyword to indicate legacy 
ntuple support, and then adding something like "class-rule-add", and 
"class-rule-del" to add support for the network flow classifier calls?

Then for display we could add "ntuple-all", "class-rule-all", and 
"class-rule %d" as display options with the default being to go through 
and do both "ntuple-all" and "class-rule-all" if neither are specified. 
  Do you think something like that would work?

>> @@ -978,8 +1024,37 @@ static void parse_cmdline(int argc, char **argp)
>>                                                show_usage(1);
>>                                        else
>>                                                rx_fhash_changed = 1;
>> -                             } else
>> +                             } else if (!strcmp(argp[i],
>> +                                                "rx-class-rule-del")) {
>> +                                     i += 1;
>> +                                     if (i>= argc) {
>> +                                             show_usage(1);
>> +                                             break;
>> +                                     }
>> +                                     rx_class_rule_del =
>> +                                             strtol(argp[i], NULL, 0);
>> +                                     if (rx_class_rule_del<  0)
>> +                                             show_usage(1);
>
> Use get_uint_range(argp[i], 0, INT_MAX).

Will be fixed in the next patch.

>> +                             } else if (!strcmp(argp[i],
>> +                                                "rx-class-rule-add")) {
>> +                                     i += 1;
>> +                                     if (i>= argc) {
>> +                                             show_usage(1);
>> +                                             break;
>> +                                     }
>> +                                     if (rxclass_parse_ruleopts(&argp[i],
>> +                                                                argc - i,
>> +&rx_rule_fs,
>> +&rxclass_loc_valid)<  0) {
>> +                                             show_usage(1);
>> +                                     } else {
>> +                                             i = argc;
>> +                                             rx_class_rule_added = 1;
>> +                                     }
>> +                             } else {
>>                                        show_usage(1);
>> +                             }
>> +
>>                                break;
>>                        }
>>                        if (mode == MODE_SRXFHINDIR) {
>> @@ -1917,9 +1992,12 @@ static int dump_rxfhash(int fhash, u64 val)
>>        case SCTP_V4_FLOW:
>>                fprintf(stdout, "SCTP over IPV4 flows");
>>                break;
>> -     case AH_ESP_V4_FLOW:
>
> I believe this is still a valid type for flow hashing.
>

I just looked and it is since this is something from the original patch. 
  I'm not even really sure why the patch modified this piece except for 
maybe to try and correct the fact that AH and ESP being merged makes it 
much more difficult to separate.  For now what I think I will do is spin 
this off into a separate patch that will add support for displaying 
AH_V4/6_FLOW and add support for setting and displaying ESP_V4/6_FLOW.

>> +     case AH_V4_FLOW:
>>                fprintf(stdout, "IPSEC AH over IPV4 flows");
>>                break;
>> +     case ESP_V4_FLOW:
>> +             fprintf(stdout, "IPSEC ESP over IPV4 flows");
>> +             break;
>>        case TCP_V6_FLOW:
>>                fprintf(stdout, "TCP over IPV6 flows");
>>                break;
>> @@ -1929,9 +2007,12 @@ static int dump_rxfhash(int fhash, u64 val)
>>        case SCTP_V6_FLOW:
>>                fprintf(stdout, "SCTP over IPV6 flows");
>>                break;
>> -     case AH_ESP_V6_FLOW:
>
> Same as for AH_ESP_V4_FLOW.
>

I will just leave the value in for the next patch.

>> +     case AH_V6_FLOW:
>>                fprintf(stdout, "IPSEC AH over IPV6 flows");
>>                break;
>> +     case ESP_V6_FLOW:
>> +             fprintf(stdout, "IPSEC ESP over IPV6 flows");
>> +             break;
>>        default:
>>                break;
>>        }
>> @@ -2911,14 +2992,12 @@ static int do_gstats(int fd, struct ifreq *ifr)
>>        return 0;
>>   }
>>
>> -
>>   static int do_srxclass(int fd, struct ifreq *ifr)
>>   {
>>        int err;
>> +     struct ethtool_rxnfc nfccmd;
>>
>>        if (rx_fhash_changed) {
>> -             struct ethtool_rxnfc nfccmd;
>> -
>>                nfccmd.cmd = ETHTOOL_SRXFH;
>>                nfccmd.flow_type = rx_fhash_set;
>>                nfccmd.data = rx_fhash_val;
>> @@ -2930,6 +3009,20 @@ static int do_srxclass(int fd, struct ifreq *ifr)
>>
>>        }
>>
>> +     if (rx_class_rule_added) {
>> +             err = rxclass_rule_ins(fd, ifr,&rx_rule_fs,
>> +                                    rxclass_loc_valid);
>> +             if (err<  0)
>> +                     fprintf(stderr, "Cannot insert RX classification rule\n");
>> +     }
>> +
>> +     if (rx_class_rule_del>= 0) {
>> +             err = rxclass_rule_del(fd, ifr, rx_class_rule_del);
>> +
>> +             if (err<  0)
>> +                     fprintf(stderr, "Cannot delete RX classification rule\n");
>> +     }
>> +
>>        return 0;
>>   }
>
> This needs to return 1 on error (I know that's an existing bug, but
> don't compound it).
>

This will be fixed for the next patch.

>> @@ -2950,6 +3043,31 @@ static int do_grxclass(int fd, struct ifreq *ifr)
>>                        dump_rxfhash(rx_fhash_get, nfccmd.data);
>>        }
>>
>> +     if (rx_rings_get) {
>> +             struct ethtool_rxnfc nfccmd;
>> +
>> +             nfccmd.cmd = ETHTOOL_GRXRINGS;
>> +             ifr->ifr_data = (caddr_t)&nfccmd;
>> +             err = ioctl(fd, SIOCETHTOOL, ifr);
>> +             if (err<  0)
>> +                     perror("Cannot get RX rings");
>> +             else
>> +                     fprintf(stdout, "%d RX rings available\n",
>> +                             (int)nfccmd.data);
>> +     }
>> +
>> +     if (rx_class_rule_get>= 0) {
>> +             err = rxclass_rule_get(fd, ifr, rx_class_rule_get);
>> +             if (err<  0)
>> +                     fprintf(stderr, "Cannot get RX classification rule\n");
>> +     }
>> +
>> +     if (rx_class_rule_getall) {
>> +             err = rxclass_rule_getall(fd, ifr);
>> +             if (err<  0)
>> +                     fprintf(stderr, "RX classification rule retrieval failed\n");
>> +     }
>> +
>>        return 0;
>>   }
>
> Ditto for this.
>

I'll have it fixed for the next patch.

>> diff --git a/rxclass.c b/rxclass.c
>> new file mode 100644
>> index 0000000..fd01a32
>> --- /dev/null
>> +++ b/rxclass.c
>> @@ -0,0 +1,809 @@
>> +/*
>> + * Copyright (C) 2008 Sun Microsystems, Inc. All rights reserved.
>> + */
>> +#include<stdio.h>
>> +#include<stdint.h>
>> +#include<stddef.h>
>> +#include<stdlib.h>
>> +#include<string.h>
>> +#include<strings.h>
>> +
>> +#include<linux/sockios.h>
>> +#include<arpa/inet.h>
>> +#include "ethtool-util.h"
>> +#include "ethtool-bitops.h"
>> +
>> +/*
>> + * This is a rule manager implementation for ordering rx flow
>> + * classification rules in a longest prefix first match order.
>> + * The assumption is that this rule manager is the only one adding rules to
>> + * the device's hardware classifier.
>> + */
>> +
>> +struct rmgr_ctrl {
>> +     /* slot contains a bitmap indicating which filters are valid */
>> +     unsigned long           *slot;
>> +     __u32                   n_rules;
>> +     __u32                   size;
>> +};
>> +
>> +static struct rmgr_ctrl rmgr;
>> +static int rmgr_init_done = 0;
>> +
>> +#ifndef SIOCETHTOOL
>> +#define SIOCETHTOOL     0x8946
>> +#endif
>
> This definition ought to be moved to ethtool-util.h rather than
> duplicated.

It will be moved in the next patch.

>> +static void rmgr_print_ipv4_rule(struct ethtool_rx_flow_spec *fsp)
>> +{
>> +     char            chan[16];
>> +     char            l4_proto[16];
>> +     __u32           sip, dip, sipm, dipm;
>> +
>> +     sip = ntohl(fsp->h_u.tcp_ip4_spec.ip4src);
>> +     dip = ntohl(fsp->h_u.tcp_ip4_spec.ip4dst);
>> +     sipm = ntohl(fsp->m_u.tcp_ip4_spec.ip4src);
>> +     dipm = ntohl(fsp->m_u.tcp_ip4_spec.ip4dst);
>> +
>> +     if (fsp->ring_cookie != RX_CLS_FLOW_DISC)
>> +             sprintf(chan, "Rx Ring [%d]", (int)fsp->ring_cookie);
>> +     else
>> +             sprintf(chan, "Discard");
>> +
>> +     switch (fsp->flow_type) {
>> +     case TCP_V4_FLOW:
>> +     case UDP_V4_FLOW:
>> +     case SCTP_V4_FLOW:
>> +     case AH_V4_FLOW:
>> +     case ESP_V4_FLOW:
>> +     case IP_USER_FLOW:
>> +             fprintf(stdout,
>> +                     "      IPv4 Rule:  ID[%d] Target[%s]\n"
>> +                     "      IP src addr[%d.%d.%d.%d] mask[%d.%d.%d.%d]\n"
>> +                     "      IP dst addr[%d.%d.%d.%d] mask[%d.%d.%d.%d]\n"
>> +                     "      IP TOS[0x%x] mask[0x%x]\n",
>
> To be consistent with other ethtool output, this should use colons
> rather than square brackets to separate field names and values.
>

I'll have that updated for the next patch.

> [...]
>> +int rxclass_parse_ruleopts(char **optstr, int opt_cnt,
>> +                        struct ethtool_rx_flow_spec *fsp,
>> +                        u_int8_t *loc_valid)
>> +{
>> +     int i = 0;
>> +
>> +     u_int8_t discard, ring_set;
>> +     u_int32_t ipsa, ipsm, ipda, ipdm, spi, spim;
>> +     u_int16_t sp, spm, dp, dpm;
>> +     u_int8_t ip_ver, proto, tos, tm;
>> +     struct in_addr in_addr;
>> +
>> +     if (*optstr == NULL || **optstr == '\0' || opt_cnt<  2) {
>> +             fprintf(stdout, "Add rule, invalid syntax\n");
>> +             return -1;
>> +     }
>> +
>> +     bzero(fsp, sizeof(struct ethtool_rx_flow_spec));
>> +     ipsa = ipda = ipsm = ipdm = spi = spim = 0x0;
>> +     sp = dp = spm = dpm = 0x0;
>> +     ip_ver = proto = tos = tm = 0x0;
>> +     discard = ring_set = 0;
>> +
>> +     if (!strcmp(optstr[i], "ip4")) {
>> +             ip_ver = ETH_RX_NFC_IP4;
>> +     } else if (!strcmp(optstr[i], "ip6")) {
>> +             fprintf(stdout, "IPv6 not yet implemented\n");
>> +             return -1;
>> +     } else {
>> +             fprintf(stdout, "Add rule, invalid syntax for IP version\n");
>> +             return -1;
>> +     }
>> +
>> +     i++;
>> +
>> +     switch (ip_ver) {
>> +     case ETH_RX_NFC_IP4:
>> +             if (!strcmp(optstr[i], "tcp"))
>> +                     fsp->flow_type = TCP_V4_FLOW;
>> +             else if (!strcmp(optstr[i], "udp"))
>> +                     fsp->flow_type = UDP_V4_FLOW;
>> +             else if (!strcmp(optstr[i], "sctp"))
>> +                     fsp->flow_type = SCTP_V4_FLOW;
>> +             else if (!strcmp(optstr[i], "ah"))
>> +                     fsp->flow_type = AH_V4_FLOW;
>> +             else if (!strcmp(optstr[i], "esp"))
>> +                     fsp->flow_type = ESP_V4_FLOW;
>> +             break;
>> +     default:
>> +             fprintf(stdout, "Add rule, Invalid IP version %d\n", ip_ver);
>> +                     return -1;
>> +     }
>> +
>> +     if (fsp->flow_type == 0) {
>> +             proto = (u_int8_t)strtoul(optstr[i], (char **)NULL, 0);
>> +             if (proto != 0) {
>> +                     fprintf(stdout, "Add rule, user defined proto %d\n",
>> +                             proto);
>> +                     fsp->flow_type = IP_USER_FLOW;
>> +                     fsp->h_u.usr_ip4_spec.proto = proto;
>> +                     fsp->h_u.usr_ip4_spec.ip_ver = ip_ver;
>> +             } else {
>> +                     fprintf(stdout, "Add rule, invalid IP proto %s\n",
>> +                             optstr[i]);
>> +                     return -1;
>> +             }
>> +     }
>> +
>> +     for (i = 2; i<  opt_cnt;) {
>> +             if (!strcmp(optstr[i], "tos")) {
>> +                     tos = (u_int8_t)strtoul(optstr[i+1], (char **)NULL,
>> +                                              0);
>> +                     tm = 0xff;
>> +                     fsp->h_u.tcp_ip4_spec.tos = tos;
>> +
>> +                     i += 2;
>> +                     if (opt_cnt>  (i+1)) {
>> +                             if (!strcmp(optstr[i], "m")) {
>> +                                     tm = (u_int8_t)strtoul(optstr[i+1],
>> +                                                            (char **)NULL,
>> +                                                            16);
>> +                                     i += 2;
>> +                             }
>> +                     }
>> +                     fsp->m_u.tcp_ip4_spec.tos = tm;
>> +             } else if (!strcmp(optstr[i], "sip")) {
> [...]
>
> These keyword names must be made consistent with those used for the -U
> (--config-ntuple) option.
>

I will update the names to be consistent with the ntuple options, 
however I would prefer to keep the option of short-cutting the mask via 
the "m" value.  It will not be hard to make it support both since the 
pattern would be to test for either "m" or "%s-mask".

> Also, they can be parsed much more concisely using the new option types
> I defined a while back for struct cmdline_info.
>

I'm already looking into using something like the cmdline_info to do the 
parsing, however one thing I would like to retain is the mask setting as 
a part of setting the value.  Also since rxclass is being passed a 
pointer it is going to have to work with relative offsets instead of 
fixed values for the location of the fields within the structure.

> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare Communications
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>


^ permalink raw reply

* [RFC PATCH 08/10] netdev: mdio-octeon.c: Convert to use device tree.
From: David Daney @ 2011-02-22 20:57 UTC (permalink / raw)
  To: linux-mips-6z/3iImG2C8G8FEW9MqTrA, ralf-6z/3iImG2C8G8FEW9MqTrA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, David Daney, David S. Miller
In-Reply-To: <1298408274-20856-1-git-send-email-ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>

Get the MDIO bus controller addresses from the device tree.

Signed-off-by: David Daney <ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
 arch/mips/cavium-octeon/octeon-platform.c |   30 ------------
 drivers/net/phy/mdio-octeon.c             |   73 +++++++++++++++++------------
 2 files changed, 43 insertions(+), 60 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index f148324..a33dcf9 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -166,36 +166,6 @@ out:
 }
 device_initcall(octeon_rng_device_init);
 
-/* Octeon SMI/MDIO interface.  */
-static int __init octeon_mdiobus_device_init(void)
-{
-	struct platform_device *pd;
-	int ret = 0;
-
-	if (octeon_is_simulation())
-		return 0; /* No mdio in the simulator. */
-
-	/* The bus number is the platform_device id.  */
-	pd = platform_device_alloc("mdio-octeon", 0);
-	if (!pd) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	ret = platform_device_add(pd);
-	if (ret)
-		goto fail;
-
-	return ret;
-fail:
-	platform_device_put(pd);
-
-out:
-	return ret;
-
-}
-device_initcall(octeon_mdiobus_device_init);
-
 /* Octeon mgmt port Ethernet interface.  */
 static int __init octeon_mgmt_device_init(void)
 {
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index bd12ba9..b04c18c 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -6,10 +6,14 @@
  * Copyright (C) 2009 Cavium Networks
  */
 
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_mdio.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/phy.h>
 
 #include <asm/octeon/octeon.h>
@@ -18,9 +22,15 @@
 #define DRV_VERSION "1.0"
 #define DRV_DESCRIPTION "Cavium Networks Octeon SMI/MDIO driver"
 
+#define SMI_CMD		0x0
+#define SMI_WR_DAT	0x8
+#define SMI_RD_DAT	0x10
+#define SMI_CLK		0x18
+#define SMI_EN		0x20
+
 struct octeon_mdiobus {
 	struct mii_bus *mii_bus;
-	int unit;
+	u64 register_base;
 	int phy_irq[PHY_MAX_ADDR];
 };
 
@@ -35,15 +45,15 @@ static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
 	smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */
 	smi_cmd.s.phy_adr = phy_id;
 	smi_cmd.s.reg_adr = regnum;
-	cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
+	cvmx_write_csr(p->register_base + SMI_CMD, smi_cmd.u64);
 
 	do {
 		/*
 		 * Wait 1000 clocks so we don't saturate the RSL bus
 		 * doing reads.
 		 */
-		cvmx_wait(1000);
-		smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(p->unit));
+		__delay(1000);
+		smi_rd.u64 = cvmx_read_csr(p->register_base + SMI_RD_DAT);
 	} while (smi_rd.s.pending && --timeout);
 
 	if (smi_rd.s.val)
@@ -62,21 +72,21 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
 
 	smi_wr.u64 = 0;
 	smi_wr.s.dat = val;
-	cvmx_write_csr(CVMX_SMIX_WR_DAT(p->unit), smi_wr.u64);
+	cvmx_write_csr(p->register_base + SMI_WR_DAT, smi_wr.u64);
 
 	smi_cmd.u64 = 0;
 	smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */
 	smi_cmd.s.phy_adr = phy_id;
 	smi_cmd.s.reg_adr = regnum;
-	cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
+	cvmx_write_csr(p->register_base + SMI_CMD, smi_cmd.u64);
 
 	do {
 		/*
 		 * Wait 1000 clocks so we don't saturate the RSL bus
 		 * doing reads.
 		 */
-		cvmx_wait(1000);
-		smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(p->unit));
+		__delay(1000);
+		smi_wr.u64 = cvmx_read_csr(p->register_base + SMI_WR_DAT);
 	} while (smi_wr.s.pending && --timeout);
 
 	if (timeout <= 0)
@@ -85,11 +95,11 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
 	return 0;
 }
 
-static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
+static int __devinit octeon_mdiobus_probe(struct platform_device *pdev,
+					  const struct of_device_id *match)
 {
 	struct octeon_mdiobus *bus;
 	union cvmx_smix_en smi_en;
-	int i;
 	int err = -ENOENT;
 
 	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
@@ -97,8 +107,7 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	/* The platform_device id is our unit number.  */
-	bus->unit = pdev->id;
-
+	bus->register_base = (u64)of_iomap(pdev->dev.of_node, 0);
 	bus->mii_bus = mdiobus_alloc();
 
 	if (!bus->mii_bus)
@@ -106,19 +115,13 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
 
 	smi_en.u64 = 0;
 	smi_en.s.en = 1;
-	cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+	cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64);
 
-	/*
-	 * Standard Octeon evaluation boards don't support phy
-	 * interrupts, we need to poll.
-	 */
-	for (i = 0; i < PHY_MAX_ADDR; i++)
-		bus->phy_irq[i] = PHY_POLL;
 
 	bus->mii_bus->priv = bus;
 	bus->mii_bus->irq = bus->phy_irq;
 	bus->mii_bus->name = "mdio-octeon";
-	snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%x", bus->unit);
+	snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base);
 	bus->mii_bus->parent = &pdev->dev;
 
 	bus->mii_bus->read = octeon_mdiobus_read;
@@ -126,7 +129,7 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
 
 	dev_set_drvdata(&pdev->dev, bus);
 
-	err = mdiobus_register(bus->mii_bus);
+	err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node);
 	if (err)
 		goto err_register;
 
@@ -137,9 +140,9 @@ err_register:
 	mdiobus_free(bus->mii_bus);
 
 err:
-	devm_kfree(&pdev->dev, bus);
 	smi_en.u64 = 0;
-	cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+	cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64);
+	devm_kfree(&pdev->dev, bus);
 	return err;
 }
 
@@ -153,14 +156,24 @@ static int __devexit octeon_mdiobus_remove(struct platform_device *pdev)
 	mdiobus_unregister(bus->mii_bus);
 	mdiobus_free(bus->mii_bus);
 	smi_en.u64 = 0;
-	cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+	cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64);
+	devm_kfree(&pdev->dev, bus);
 	return 0;
 }
 
-static struct platform_driver octeon_mdiobus_driver = {
+static struct of_device_id octeon_mdiobus_match[] = {
+	{
+		.compatible = "octeon,mdio",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, octeon_mdiobus_match);
+
+static struct of_platform_driver octeon_mdiobus_driver = {
 	.driver = {
 		.name		= "mdio-octeon",
 		.owner		= THIS_MODULE,
+		.of_match_table = octeon_mdiobus_match,
 	},
 	.probe		= octeon_mdiobus_probe,
 	.remove		= __devexit_p(octeon_mdiobus_remove),
@@ -174,12 +187,12 @@ EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency);
 
 static int __init octeon_mdiobus_mod_init(void)
 {
-	return platform_driver_register(&octeon_mdiobus_driver);
+	return of_register_platform_driver(&octeon_mdiobus_driver);
 }
 
 static void __exit octeon_mdiobus_mod_exit(void)
 {
-	platform_driver_unregister(&octeon_mdiobus_driver);
+	of_unregister_platform_driver(&octeon_mdiobus_driver);
 }
 
 module_init(octeon_mdiobus_mod_init);
-- 
1.7.2.3

^ permalink raw reply related

* [RFC PATCH 09/10] netdev: octeon_mgmt: Convert to use device tree.
From: David Daney @ 2011-02-22 20:57 UTC (permalink / raw)
  To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
  Cc: David Daney, David S. Miller, netdev
In-Reply-To: <1298408274-20856-1-git-send-email-ddaney@caviumnetworks.com>

The device tree will supply the register bank base addresses, make
register addressing relative to those.  PHY connection is now
described by the device tree.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
 arch/mips/cavium-octeon/octeon-platform.c |   62 -------
 drivers/net/octeon/octeon_mgmt.c          |  265 +++++++++++++++++------------
 2 files changed, 160 insertions(+), 167 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index a33dcf9..3a3867b 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -166,68 +166,6 @@ out:
 }
 device_initcall(octeon_rng_device_init);
 
-/* Octeon mgmt port Ethernet interface.  */
-static int __init octeon_mgmt_device_init(void)
-{
-	struct platform_device *pd;
-	int ret = 0;
-	int port, num_ports;
-
-	struct resource mgmt_port_resource = {
-		.flags	= IORESOURCE_IRQ,
-		.start	= -1,
-		.end	= -1
-	};
-
-	if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX))
-		return 0;
-
-	if (OCTEON_IS_MODEL(OCTEON_CN56XX))
-		num_ports = 1;
-	else
-		num_ports = 2;
-
-	for (port = 0; port < num_ports; port++) {
-		pd = platform_device_alloc("octeon_mgmt", port);
-		if (!pd) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		/* No DMA restrictions */
-		pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
-		pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
-
-		switch (port) {
-		case 0:
-			mgmt_port_resource.start = OCTEON_IRQ_MII0;
-			break;
-		case 1:
-			mgmt_port_resource.start = OCTEON_IRQ_MII1;
-			break;
-		default:
-			BUG();
-		}
-		mgmt_port_resource.end = mgmt_port_resource.start;
-
-		ret = platform_device_add_resources(pd, &mgmt_port_resource, 1);
-
-		if (ret)
-			goto fail;
-
-		ret = platform_device_add(pd);
-		if (ret)
-			goto fail;
-	}
-	return ret;
-fail:
-	platform_device_put(pd);
-
-out:
-	return ret;
-
-}
-device_initcall(octeon_mgmt_device_init);
-
 #ifdef CONFIG_USB
 
 static int __init octeon_ehci_device_init(void)
diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c
index b264f0f..6c301c7 100644
--- a/drivers/net/octeon/octeon_mgmt.c
+++ b/drivers/net/octeon/octeon_mgmt.c
@@ -6,16 +6,21 @@
  * Copyright (C) 2009 Cavium Networks
  */
 
-#include <linux/capability.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
+#include <linux/of_platform.h>
+#include <linux/capability.h>
+#include <linux/of_address.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
 #include <linux/if_vlan.h>
+#include <linux/of_mdio.h>
+#include <linux/of_irq.h>
+#include <linux/of_net.h>
+#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/phy.h>
-#include <linux/spinlock.h>
 
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/cvmx-mixx-defs.h>
@@ -55,8 +60,56 @@ union mgmt_port_ring_entry {
 	} s;
 };
 
+#define MIX_ORING1	0x0
+#define MIX_ORING2	0x8
+#define MIX_IRING1	0x10
+#define MIX_IRING2	0x18
+#define MIX_CTL		0x20
+#define MIX_IRHWM	0x28
+#define MIX_IRCNT	0x30
+#define MIX_ORHWM	0x38
+#define MIX_ORCNT	0x40
+#define MIX_ISR		0x48
+#define MIX_INTENA	0x50
+#define MIX_REMCNT	0x58
+#define MIX_BIST	0x78
+
+#define AGL_GMX_PRT_CFG			0x10
+#define AGL_GMX_RX_FRM_CTL		0x18
+#define AGL_GMX_RX_FRM_MAX		0x30
+#define AGL_GMX_RX_JABBER		0x38
+#define AGL_GMX_RX_STATS_CTL		0x50
+
+#define AGL_GMX_RX_STATS_PKTS_DRP	0xb0
+#define AGL_GMX_RX_STATS_OCTS_DRP	0xb8
+#define AGL_GMX_RX_STATS_PKTS_BAD	0xc0
+
+#define AGL_GMX_RX_ADR_CTL		0x100
+#define AGL_GMX_RX_ADR_CAM_EN		0x108
+#define AGL_GMX_RX_ADR_CAM0		0x180
+#define AGL_GMX_RX_ADR_CAM1		0x188
+#define AGL_GMX_RX_ADR_CAM2		0x190
+#define AGL_GMX_RX_ADR_CAM3		0x198
+#define AGL_GMX_RX_ADR_CAM4		0x1a0
+#define AGL_GMX_RX_ADR_CAM5		0x1a8
+
+#define AGL_GMX_TX_STATS_CTL		0x268
+#define AGL_GMX_TX_CTL			0x270
+#define AGL_GMX_TX_STAT0		0x280
+#define AGL_GMX_TX_STAT1		0x288
+#define AGL_GMX_TX_STAT2		0x290
+#define AGL_GMX_TX_STAT3		0x298
+#define AGL_GMX_TX_STAT4		0x2a0
+#define AGL_GMX_TX_STAT5		0x2a8
+#define AGL_GMX_TX_STAT6		0x2b0
+#define AGL_GMX_TX_STAT7		0x2b8
+#define AGL_GMX_TX_STAT8		0x2c0
+#define AGL_GMX_TX_STAT9		0x2c8
+
 struct octeon_mgmt {
 	struct net_device *netdev;
+	u64 mix;
+	u64 agl;
 	int port;
 	int irq;
 	u64 *tx_ring;
@@ -82,31 +135,30 @@ struct octeon_mgmt {
 	struct napi_struct napi;
 	struct tasklet_struct tx_clean_tasklet;
 	struct phy_device *phydev;
+	struct device_node *phy_np;
 };
 
 static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
 {
-	int port = p->port;
 	union cvmx_mixx_intena mix_intena;
 	unsigned long flags;
 
 	spin_lock_irqsave(&p->lock, flags);
-	mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
+	mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
 	mix_intena.s.ithena = enable ? 1 : 0;
-	cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
 	spin_unlock_irqrestore(&p->lock, flags);
 }
 
 static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable)
 {
-	int port = p->port;
 	union cvmx_mixx_intena mix_intena;
 	unsigned long flags;
 
 	spin_lock_irqsave(&p->lock, flags);
-	mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
+	mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
 	mix_intena.s.othena = enable ? 1 : 0;
-	cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
 	spin_unlock_irqrestore(&p->lock, flags);
 }
 
@@ -143,7 +195,6 @@ static unsigned int ring_size_to_bytes(unsigned int ring_size)
 static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 
 	while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) {
 		unsigned int size;
@@ -174,24 +225,23 @@ static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
 			(p->rx_next_fill + 1) % OCTEON_MGMT_RX_RING_SIZE;
 		p->rx_current_fill++;
 		/* Ring the bell.  */
-		cvmx_write_csr(CVMX_MIXX_IRING2(port), 1);
+		cvmx_write_csr(p->mix + MIX_IRING2, 1);
 	}
 }
 
 static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
 {
-	int port = p->port;
 	union cvmx_mixx_orcnt mix_orcnt;
 	union mgmt_port_ring_entry re;
 	struct sk_buff *skb;
 	int cleaned = 0;
 	unsigned long flags;
 
-	mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+	mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT);
 	while (mix_orcnt.s.orcnt) {
 		spin_lock_irqsave(&p->tx_list.lock, flags);
 
-		mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+		mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT);
 
 		if (mix_orcnt.s.orcnt == 0) {
 			spin_unlock_irqrestore(&p->tx_list.lock, flags);
@@ -211,7 +261,7 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
 		mix_orcnt.s.orcnt = 1;
 
 		/* Acknowledge to hardware that we have the buffer.  */
-		cvmx_write_csr(CVMX_MIXX_ORCNT(port), mix_orcnt.u64);
+		cvmx_write_csr(p->mix + MIX_ORCNT, mix_orcnt.u64);
 		p->tx_current_fill--;
 
 		spin_unlock_irqrestore(&p->tx_list.lock, flags);
@@ -221,7 +271,7 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
 		dev_kfree_skb_any(skb);
 		cleaned++;
 
-		mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+		mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT);
 	}
 
 	if (cleaned && netif_queue_stopped(p->netdev))
@@ -238,13 +288,12 @@ static void octeon_mgmt_clean_tx_tasklet(unsigned long arg)
 static void octeon_mgmt_update_rx_stats(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	unsigned long flags;
 	u64 drop, bad;
 
 	/* These reads also clear the count registers.  */
-	drop = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port));
-	bad = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port));
+	drop = cvmx_read_csr(p->agl + AGL_GMX_RX_STATS_PKTS_DRP);
+	bad = cvmx_read_csr(p->agl + AGL_GMX_RX_STATS_PKTS_BAD);
 
 	if (drop || bad) {
 		/* Do an atomic update. */
@@ -258,15 +307,14 @@ static void octeon_mgmt_update_rx_stats(struct net_device *netdev)
 static void octeon_mgmt_update_tx_stats(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	unsigned long flags;
 
 	union cvmx_agl_gmx_txx_stat0 s0;
 	union cvmx_agl_gmx_txx_stat1 s1;
 
 	/* These reads also clear the count registers.  */
-	s0.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT0(port));
-	s1.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT1(port));
+	s0.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_STAT0);
+	s1.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_STAT1);
 
 	if (s0.s.xsdef || s0.s.xscol || s1.s.scol || s1.s.mcol) {
 		/* Do an atomic update. */
@@ -305,7 +353,6 @@ static u64 octeon_mgmt_dequeue_rx_buffer(struct octeon_mgmt *p,
 
 static int octeon_mgmt_receive_one(struct octeon_mgmt *p)
 {
-	int port = p->port;
 	struct net_device *netdev = p->netdev;
 	union cvmx_mixx_ircnt mix_ircnt;
 	union mgmt_port_ring_entry re;
@@ -378,18 +425,17 @@ done:
 	/* Tell the hardware we processed a packet.  */
 	mix_ircnt.u64 = 0;
 	mix_ircnt.s.ircnt = 1;
-	cvmx_write_csr(CVMX_MIXX_IRCNT(port), mix_ircnt.u64);
+	cvmx_write_csr(p->mix + MIX_IRCNT, mix_ircnt.u64);
 	return rc;
 }
 
 static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget)
 {
-	int port = p->port;
 	unsigned int work_done = 0;
 	union cvmx_mixx_ircnt mix_ircnt;
 	int rc;
 
-	mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
+	mix_ircnt.u64 = cvmx_read_csr(p->mix + MIX_IRCNT);
 	while (work_done < budget && mix_ircnt.s.ircnt) {
 
 		rc = octeon_mgmt_receive_one(p);
@@ -397,7 +443,7 @@ static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget)
 			work_done++;
 
 		/* Check for more packets. */
-		mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
+		mix_ircnt.u64 = cvmx_read_csr(p->mix + MIX_IRCNT);
 	}
 
 	octeon_mgmt_rx_fill_ring(p->netdev);
@@ -431,16 +477,16 @@ static void octeon_mgmt_reset_hw(struct octeon_mgmt *p)
 	union cvmx_agl_gmx_bist agl_gmx_bist;
 
 	mix_ctl.u64 = 0;
-	cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
+	cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
 	do {
-		mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(p->port));
+		mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL);
 	} while (mix_ctl.s.busy);
 	mix_ctl.s.reset = 1;
-	cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
-	cvmx_read_csr(CVMX_MIXX_CTL(p->port));
+	cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
+	cvmx_read_csr(p->mix + MIX_CTL);
 	cvmx_wait(64);
 
-	mix_bist.u64 = cvmx_read_csr(CVMX_MIXX_BIST(p->port));
+	mix_bist.u64 = cvmx_read_csr(p->mix + MIX_BIST);
 	if (mix_bist.u64)
 		dev_warn(p->dev, "MIX failed BIST (0x%016llx)\n",
 			(unsigned long long)mix_bist.u64);
@@ -471,7 +517,6 @@ static void octeon_mgmt_cam_state_add(struct octeon_mgmt_cam_state *cs,
 static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	union cvmx_agl_gmx_rxx_adr_ctl adr_ctl;
 	union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx;
 	unsigned long flags;
@@ -517,29 +562,29 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
 	spin_lock_irqsave(&p->lock, flags);
 
 	/* Disable packet I/O. */
-	agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+	agl_gmx_prtx.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
 	prev_packet_enable = agl_gmx_prtx.s.en;
 	agl_gmx_prtx.s.en = 0;
-	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
+	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64);
 
 	adr_ctl.u64 = 0;
 	adr_ctl.s.cam_mode = cam_mode;
 	adr_ctl.s.mcst = multicast_mode;
 	adr_ctl.s.bcst = 1;     /* Allow broadcast */
 
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), adr_ctl.u64);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CTL, adr_ctl.u64);
 
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), cam_state.cam[0]);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), cam_state.cam[1]);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), cam_state.cam[2]);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), cam_state.cam[3]);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), cam_state.cam[4]);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), cam_state.cam[5]);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), cam_state.cam_mask);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM0, cam_state.cam[0]);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM1, cam_state.cam[1]);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM2, cam_state.cam[2]);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM3, cam_state.cam[3]);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM4, cam_state.cam[4]);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM5, cam_state.cam[5]);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM_EN, cam_state.cam_mask);
 
 	/* Restore packet I/O. */
 	agl_gmx_prtx.s.en = prev_packet_enable;
-	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
+	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64);
 
 	spin_unlock_irqrestore(&p->lock, flags);
 }
@@ -561,7 +606,6 @@ static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr)
 static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM;
 
 	/*
@@ -577,8 +621,8 @@ static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu)
 
 	netdev->mtu = new_mtu;
 
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_MAX(port), size_without_fcs);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_JABBER(port),
+	cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_MAX, size_without_fcs);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_JABBER,
 		       (size_without_fcs + 7) & 0xfff8);
 
 	return 0;
@@ -588,14 +632,13 @@ static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id)
 {
 	struct net_device *netdev = dev_id;
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	union cvmx_mixx_isr mixx_isr;
 
-	mixx_isr.u64 = cvmx_read_csr(CVMX_MIXX_ISR(port));
+	mixx_isr.u64 = cvmx_read_csr(p->mix + MIX_ISR);
 
 	/* Clear any pending interrupts */
-	cvmx_write_csr(CVMX_MIXX_ISR(port), mixx_isr.u64);
-	cvmx_read_csr(CVMX_MIXX_ISR(port));
+	cvmx_write_csr(p->mix + MIX_ISR, mixx_isr.u64);
+	cvmx_read_csr(p->mix + MIX_ISR);
 
 	if (mixx_isr.s.irthresh) {
 		octeon_mgmt_disable_rx_irq(p);
@@ -626,7 +669,6 @@ static int octeon_mgmt_ioctl(struct net_device *netdev,
 static void octeon_mgmt_adjust_link(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
 	unsigned long flags;
 	int link_changed = 0;
@@ -637,11 +679,9 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev)
 			link_changed = 1;
 		if (p->last_duplex != p->phydev->duplex) {
 			p->last_duplex = p->phydev->duplex;
-			prtx_cfg.u64 =
-				cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+			prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
 			prtx_cfg.s.duplex = p->phydev->duplex;
-			cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port),
-				       prtx_cfg.u64);
+			cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
 		}
 	} else {
 		if (p->last_link)
@@ -667,18 +707,16 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev)
 static int octeon_mgmt_init_phy(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	char phy_id[20];
 
-	if (octeon_is_simulation()) {
+	if (octeon_is_simulation() || p->phy_np == NULL) {
 		/* No PHYs in the simulator. */
 		netif_carrier_on(netdev);
 		return 0;
 	}
 
-	snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", p->port);
-
-	p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0,
-				PHY_INTERFACE_MODE_MII);
+	p->phydev = of_phy_connect(netdev, p->phy_np,
+				   octeon_mgmt_adjust_link, 0,
+				   PHY_INTERFACE_MODE_MII);
 
 	if (IS_ERR(p->phydev)) {
 		p->phydev = NULL;
@@ -734,14 +772,14 @@ static int octeon_mgmt_open(struct net_device *netdev)
 
 	octeon_mgmt_reset_hw(p);
 
-	mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
+	mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL);
 
 	/* Bring it out of reset if needed. */
 	if (mix_ctl.s.reset) {
 		mix_ctl.s.reset = 0;
-		cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
+		cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
 		do {
-			mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
+			mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL);
 		} while (mix_ctl.s.reset);
 	}
 
@@ -752,17 +790,17 @@ static int octeon_mgmt_open(struct net_device *netdev)
 	oring1.u64 = 0;
 	oring1.s.obase = p->tx_ring_handle >> 3;
 	oring1.s.osize = OCTEON_MGMT_TX_RING_SIZE;
-	cvmx_write_csr(CVMX_MIXX_ORING1(port), oring1.u64);
+	cvmx_write_csr(p->mix + MIX_ORING1, oring1.u64);
 
 	iring1.u64 = 0;
 	iring1.s.ibase = p->rx_ring_handle >> 3;
 	iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE;
-	cvmx_write_csr(CVMX_MIXX_IRING1(port), iring1.u64);
+	cvmx_write_csr(p->mix + MIX_IRING1, iring1.u64);
 
 	/* Disable packet I/O. */
-	prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
 	prtx_cfg.s.en = 0;
-	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
+	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
 
 	memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN);
 	octeon_mgmt_set_mac_address(netdev, &sa);
@@ -779,7 +817,7 @@ static int octeon_mgmt_open(struct net_device *netdev)
 	mix_ctl.s.nbtarb = 0;       /* Arbitration mode */
 	/* MII CB-request FIFO programmable high watermark */
 	mix_ctl.s.mrq_hwm = 1;
-	cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
+	cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
 
 	if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
 	    || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
@@ -806,16 +844,16 @@ static int octeon_mgmt_open(struct net_device *netdev)
 
 	/* Clear statistics. */
 	/* Clear on read. */
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_CTL(port), 1);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port), 0);
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port), 0);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_CTL, 1);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_PKTS_DRP, 0);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_PKTS_BAD, 0);
 
-	cvmx_write_csr(CVMX_AGL_GMX_TXX_STATS_CTL(port), 1);
-	cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT0(port), 0);
-	cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT1(port), 0);
+	cvmx_write_csr(p->agl + AGL_GMX_TX_STATS_CTL, 1);
+	cvmx_write_csr(p->agl + AGL_GMX_TX_STAT0, 0);
+	cvmx_write_csr(p->agl + AGL_GMX_TX_STAT1, 0);
 
 	/* Clear any pending interrupts */
-	cvmx_write_csr(CVMX_MIXX_ISR(port), cvmx_read_csr(CVMX_MIXX_ISR(port)));
+	cvmx_write_csr(p->mix + MIX_ISR, cvmx_read_csr(p->mix + MIX_ISR));
 
 	if (request_irq(p->irq, octeon_mgmt_interrupt, 0, netdev->name,
 			netdev)) {
@@ -826,18 +864,18 @@ static int octeon_mgmt_open(struct net_device *netdev)
 	/* Interrupt every single RX packet */
 	mix_irhwm.u64 = 0;
 	mix_irhwm.s.irhwm = 0;
-	cvmx_write_csr(CVMX_MIXX_IRHWM(port), mix_irhwm.u64);
+	cvmx_write_csr(p->mix + MIX_IRHWM, mix_irhwm.u64);
 
 	/* Interrupt when we have 1 or more packets to clean.  */
 	mix_orhwm.u64 = 0;
 	mix_orhwm.s.orhwm = 1;
-	cvmx_write_csr(CVMX_MIXX_ORHWM(port), mix_orhwm.u64);
+	cvmx_write_csr(p->mix + MIX_ORHWM, mix_orhwm.u64);
 
 	/* Enable receive and transmit interrupts */
 	mix_intena.u64 = 0;
 	mix_intena.s.ithena = 1;
 	mix_intena.s.othena = 1;
-	cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
 
 
 	/* Enable packet I/O. */
@@ -868,7 +906,7 @@ static int octeon_mgmt_open(struct net_device *netdev)
 	 * frame.  GMX checks that the PREAMBLE is sent correctly.
 	 */
 	rxx_frm_ctl.s.pre_chk = 1;
-	cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_CTL(port), rxx_frm_ctl.u64);
+	cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
 
 	/* Enable the AGL block */
 	agl_gmx_inf_mode.u64 = 0;
@@ -876,13 +914,13 @@ static int octeon_mgmt_open(struct net_device *netdev)
 	cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
 
 	/* Configure the port duplex and enables */
-	prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
 	prtx_cfg.s.tx_en = 1;
 	prtx_cfg.s.rx_en = 1;
 	prtx_cfg.s.en = 1;
 	p->last_duplex = 1;
 	prtx_cfg.s.duplex = p->last_duplex;
-	cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
+	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
 
 	p->last_link = 0;
 	netif_carrier_off(netdev);
@@ -946,7 +984,6 @@ static int octeon_mgmt_stop(struct net_device *netdev)
 static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	union mgmt_port_ring_entry re;
 	unsigned long flags;
 	int rv = NETDEV_TX_BUSY;
@@ -990,7 +1027,7 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
 	netdev->stats.tx_bytes += skb->len;
 
 	/* Ring the bell.  */
-	cvmx_write_csr(CVMX_MIXX_ORING2(port), 1);
+	cvmx_write_csr(p->mix + MIX_ORING2, 1);
 
 	rv = NETDEV_TX_OK;
 out:
@@ -1067,12 +1104,14 @@ static const struct net_device_ops octeon_mgmt_ops = {
 #endif
 };
 
-static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
+static int __devinit octeon_mgmt_probe(struct platform_device *pdev,
+				       const struct of_device_id *match)
 {
-	struct resource *res_irq;
 	struct net_device *netdev;
 	struct octeon_mgmt *p;
-	int i;
+	const __be32 *data;
+	const u8 *mac;
+	int len;
 
 	netdev = alloc_etherdev(sizeof(struct octeon_mgmt));
 	if (netdev == NULL)
@@ -1086,14 +1125,21 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
 	p->netdev = netdev;
 	p->dev = &pdev->dev;
 
-	p->port = pdev->id;
+	data = of_get_property(pdev->dev.of_node, "unit-number", &len);
+	if (data && len == sizeof(*data))
+		p->port = be32_to_cpup(data);
+	else
+		p->port = 0;
+
 	snprintf(netdev->name, IFNAMSIZ, "mgmt%d", p->port);
 
-	res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res_irq)
+	p->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (!p->irq)
 		goto err;
 
-	p->irq = res_irq->start;
+	p->mix = (u64)of_iomap(pdev->dev.of_node, 0);
+	p->agl = (u64)of_iomap(pdev->dev.of_node, 1);
+
 	spin_lock_init(&p->lock);
 
 	skb_queue_head_init(&p->tx_list);
@@ -1104,15 +1150,15 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
 	netdev->netdev_ops = &octeon_mgmt_ops;
 	netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
 
-	/* The mgmt ports get the first N MACs.  */
-	for (i = 0; i < 6; i++)
-		netdev->dev_addr[i] = octeon_bootinfo->mac_addr_base[i];
-	netdev->dev_addr[5] += p->port;
+	mac = of_get_mac_address(pdev->dev.of_node);
+
+	if (mac)
+		memcpy(netdev->dev_addr, mac, 6);
 
-	if (p->port >= octeon_bootinfo->mac_addr_count)
-		dev_err(&pdev->dev,
-			"Error %s: Using MAC outside of the assigned range: %pM\n",
-			netdev->name, netdev->dev_addr);
+	p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
+
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
 
 	if (register_netdev(netdev))
 		goto err;
@@ -1133,10 +1179,19 @@ static int __devexit octeon_mgmt_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver octeon_mgmt_driver = {
+static struct of_device_id octeon_mgmt_match[] = {
+	{
+		.compatible = "octeon,mgmt",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, octeon_mgmt_match);
+
+static struct of_platform_driver octeon_mgmt_driver = {
 	.driver = {
 		.name		= "octeon_mgmt",
 		.owner		= THIS_MODULE,
+		.of_match_table = octeon_mgmt_match,
 	},
 	.probe		= octeon_mgmt_probe,
 	.remove		= __devexit_p(octeon_mgmt_remove),
@@ -1148,12 +1203,12 @@ static int __init octeon_mgmt_mod_init(void)
 {
 	/* Force our mdiobus driver module to be loaded first. */
 	octeon_mdiobus_force_mod_depencency();
-	return platform_driver_register(&octeon_mgmt_driver);
+	return of_register_platform_driver(&octeon_mgmt_driver);
 }
 
 static void __exit octeon_mgmt_mod_exit(void)
 {
-	platform_driver_unregister(&octeon_mgmt_driver);
+	of_unregister_platform_driver(&octeon_mgmt_driver);
 }
 
 module_init(octeon_mgmt_mod_init);
-- 
1.7.2.3

^ permalink raw reply related

* [RFC PATCH 10/10] staging: octeon_ethernet: Convert to use device tree.
From: David Daney @ 2011-02-22 20:57 UTC (permalink / raw)
  To: linux-mips-6z/3iImG2C8G8FEW9MqTrA, ralf-6z/3iImG2C8G8FEW9MqTrA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, David Daney, David S. Miller
In-Reply-To: <1298408274-20856-1-git-send-email-ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>

Get MAC address and PHY connection from the device tree.

Signed-off-by: David Daney <ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
 drivers/staging/octeon/ethernet-mdio.c   |   27 +++++----
 drivers/staging/octeon/ethernet.c        |  101 +++++++++++++++++++-----------
 drivers/staging/octeon/octeon-ethernet.h |    3 +
 3 files changed, 82 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 0e5dab7..38a0153 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
+#include <linux/of_mdio.h>
 
 #include <net/dst.h>
 
@@ -162,22 +163,24 @@ static void cvm_oct_adjust_link(struct net_device *dev)
 int cvm_oct_phy_setup_device(struct net_device *dev)
 {
 	struct octeon_ethernet *priv = netdev_priv(dev);
+	struct device_node *phy_node;
 
-	int phy_addr = cvmx_helper_board_get_mii_address(priv->port);
-	if (phy_addr != -1) {
-		char phy_id[20];
+	if (!priv->of_node)
+		return 0;
 
-		snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", phy_addr);
+	phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0);
+	if (!phy_node)
+		return 0;
 
-		priv->phydev = phy_connect(dev, phy_id, cvm_oct_adjust_link, 0,
-					PHY_INTERFACE_MODE_GMII);
+	priv->phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
+				      PHY_INTERFACE_MODE_GMII);
 
-		if (IS_ERR(priv->phydev)) {
-			priv->phydev = NULL;
-			return -1;
-		}
-		priv->last_link = 0;
-		phy_start_aneg(priv->phydev);
+	if (IS_ERR(priv->phydev)) {
+		priv->phydev = NULL;
+		return -1;
 	}
+	priv->last_link = 0;
+	phy_start_aneg(priv->phydev);
+
 	return 0;
 }
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 042adf7..87f8956 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -31,6 +31,7 @@
 #include <linux/etherdevice.h>
 #include <linux/phy.h>
 #include <linux/slab.h>
+#include <linux/of_net.h>
 
 #include <net/dst.h>
 
@@ -112,15 +113,6 @@ int rx_napi_weight = 32;
 module_param(rx_napi_weight, int, 0444);
 MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter.");
 
-/*
- * The offset from mac_addr_base that should be used for the next port
- * that is configured.  By convention, if any mgmt ports exist on the
- * chip, they get the first mac addresses, The ports controlled by
- * this driver are numbered sequencially following any mgmt addresses
- * that may exist.
- */
-static unsigned int cvm_oct_mac_addr_offset;
-
 /**
  * cvm_oct_poll_queue - Workqueue for polling operations.
  */
@@ -447,26 +439,13 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
 int cvm_oct_common_init(struct net_device *dev)
 {
 	struct octeon_ethernet *priv = netdev_priv(dev);
-	struct sockaddr sa;
-	u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) |
-		((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) |
-		((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) |
-		((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) |
-		((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) |
-		(u64)(octeon_bootinfo->mac_addr_base[5] & 0xff);
-
-	mac += cvm_oct_mac_addr_offset;
-	sa.sa_data[0] = (mac >> 40) & 0xff;
-	sa.sa_data[1] = (mac >> 32) & 0xff;
-	sa.sa_data[2] = (mac >> 24) & 0xff;
-	sa.sa_data[3] = (mac >> 16) & 0xff;
-	sa.sa_data[4] = (mac >> 8) & 0xff;
-	sa.sa_data[5] = mac & 0xff;
-
-	if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count)
-		printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:"
-			" %pM\n", dev->name, sa.sa_data);
-	cvm_oct_mac_addr_offset++;
+	struct sockaddr sa = {0};
+
+	if (priv->of_node) {
+		const u8 *mac = of_get_mac_address(priv->of_node);
+		if (mac)
+			memcpy(sa.sa_data, mac, 6);
+	}
 
 	/*
 	 * Force the interface to use the POW send if always_use_pow
@@ -594,22 +573,68 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = {
 
 extern void octeon_mdiobus_force_mod_depencency(void);
 
+static struct device_node * __init cvm_oct_of_get_child(const struct device_node *parent,
+							int reg_val)
+{
+	struct device_node *node = NULL;
+	int size;
+	const __be32 *addr;
+
+	for (;;) {
+		node = of_get_next_child(parent, node);
+		if (!node)
+			break;
+		addr = of_get_property(node, "reg", &size);
+		if (addr && (be32_to_cpu(*addr) == reg_val))
+			break;
+	}
+	return node;
+}
+
+static struct device_node * __init cvm_oct_node_for_port(struct device_node *pip,
+							 int interface, int port)
+{
+	struct device_node *ni, *np;
+
+	ni = cvm_oct_of_get_child(pip, interface);
+	if (!ni)
+		return NULL;
+
+	np = cvm_oct_of_get_child(ni, port);
+	of_node_put(ni);
+
+	return np;
+}
+
 static int __init cvm_oct_init_module(void)
 {
 	int num_interfaces;
 	int interface;
 	int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
 	int qos;
+	struct device_node *aliases;
+	const char *node_path;
+	struct device_node *pip;
 
 	octeon_mdiobus_force_mod_depencency();
 	pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
 
-	if (OCTEON_IS_MODEL(OCTEON_CN52XX))
-		cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */
-	else if (OCTEON_IS_MODEL(OCTEON_CN56XX))
-		cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */
-	else
-		cvm_oct_mac_addr_offset = 0;
+
+	aliases = of_find_node_by_path("/aliases");
+	if (!aliases) {
+		pr_err("Error: No /aliases node in device tree.");
+		return -EINVAL;
+	}
+	node_path = of_get_property(aliases, "pip", NULL);
+	if (!node_path) {
+		pr_err("Error: No /aliases/pip node in device tree.");
+		return -EINVAL;
+	}
+	pip = of_find_node_by_path(node_path);
+	if (!pip) {
+		pr_err("Error: No %s in device tree.", node_path);
+		return -EINVAL;
+	}
 
 	cvm_oct_poll_queue = create_singlethread_workqueue("octeon-ethernet");
 	if (cvm_oct_poll_queue == NULL) {
@@ -688,10 +713,11 @@ static int __init cvm_oct_init_module(void)
 		    cvmx_helper_interface_get_mode(interface);
 		int num_ports = cvmx_helper_ports_on_interface(interface);
 		int port;
+		int port_index;
 
-		for (port = cvmx_helper_get_ipd_port(interface, 0);
+		for (port_index = 0, port = cvmx_helper_get_ipd_port(interface, 0);
 		     port < cvmx_helper_get_ipd_port(interface, num_ports);
-		     port++) {
+		     port_index++, port++) {
 			struct octeon_ethernet *priv;
 			struct net_device *dev =
 			    alloc_etherdev(sizeof(struct octeon_ethernet));
@@ -702,6 +728,7 @@ static int __init cvm_oct_init_module(void)
 
 			/* Initialize the device private structure. */
 			priv = netdev_priv(dev);
+			priv->of_node = cvm_oct_node_for_port(pip, interface, port_index);
 
 			INIT_DELAYED_WORK(&priv->port_periodic_work,
 					  cvm_oct_periodic_worker);
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index d581925..9360e22 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -31,6 +31,8 @@
 #ifndef OCTEON_ETHERNET_H
 #define OCTEON_ETHERNET_H
 
+#include <linux/of.h>
+
 /**
  * This is the definition of the Ethernet driver's private
  * driver state stored in netdev_priv(dev).
@@ -59,6 +61,7 @@ struct octeon_ethernet {
 	void (*poll) (struct net_device *dev);
 	struct delayed_work	port_periodic_work;
 	struct work_struct	port_work;	/* may be unused. */
+	struct device_node	*of_node;
 };
 
 int cvm_oct_free_work(void *work_queue_entry);
-- 
1.7.2.3

^ permalink raw reply related

* Re: [PATCH] rt2x00: Use ops name instead of device name
From: Steven Rostedt @ 2011-02-22 21:08 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo Van Doorn, Ben Hutchings, LKML, netdev, Felix Fietkau,
	abogani
In-Reply-To: <20110222194724.GG12153@tuxdriver.com>

On Tue, 2011-02-22 at 14:47 -0500, John W. Linville wrote:

> I completely missed this series -- please be sure to Cc:
> linux-wireless@vger.kernel.org if you resend, and/or resend the series
> directly to me?

Hi John,

Not sure which series you were talking about. I sent out a single patch
and Cc'd you on it. But I should have sent it to linux-wireless, instead
of the net-dev list.

I don't plan on sending out any new patches. This should fix the issue.

Thanks,

-- Steve

^ permalink raw reply

* Re: [PATCH ethtool 2/3] ethtool: Regularise handling of offload flags
From: Michał Mirosław @ 2011-02-22 21:17 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev
In-Reply-To: <1298307548.2608.50.camel@bwh-desktop>

On Mon, Feb 21, 2011 at 04:59:08PM +0000, Ben Hutchings wrote:
> Use the new ETHTOOL_{G,S}FEATURES operations where available, and
> use the new structure and netif feature flags in any case.
[...]
> --- a/ethtool.c
> +++ b/ethtool.c
[...]
> +static int dump_offload(const struct ethtool_get_features_block *features)
>  {
[...]
> +	u32 value;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(off_feature_def); i++) {
> +		value = off_feature_def[i].value;
> +		printf("%s: %s%s%s\n",
> +		       off_feature_def[i].long_name,
> +		       (features->active & value) ? "on" : "off",
> +		       (features->requested & ~features->active & value) ?
> +		       " [requested on]" : "",
> +		       (~features->available & value) ? " [unchangeable]" : "");
> +	}

This would be clearer if '[requested XXX]' part was shown only when the
offload's state is different than requested.

Best Regards,
Michał Mirosław 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox