LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2][POWERPC] Fix initial lmb add region with a non-zero base
From: Paul Mackerras @ 2008-02-21  2:16 UTC (permalink / raw)
  To: David Miller; +Cc: sparclinux, linuxppc-dev, linux-kernel
In-Reply-To: <20080219.193125.04536962.davem@davemloft.net>

David Miller writes:

> I'm ambivalent but I would obviously prefer 2.6.25 because
> it would allow me to proceed more easily with my sparc64
> NUMA work as well as get your bug fixes in more smoothly.

Sounds like we should get Stephen to put it in linux-next-stable once
we're convinced it's all OK.

Paul.

^ permalink raw reply

* Re: MPC8641D PCI-Express error
From: Kumar Gala @ 2008-02-21  2:20 UTC (permalink / raw)
  To: Marco Stornelli; +Cc: LinuxPPC-Embedded
In-Reply-To: <47BC51B5.50204@coritel.it>


On Feb 20, 2008, at 10:13 AM, Marco Stornelli wrote:

> Kumar Gala wrote:
>>> Marco Stornelli wrote:
>>>
>>>> No, but I can try to backport the PCI-E code from 2.6.24 to 2.6.18
>>>> if it could help. What do you think about it? Do you think this
>>>> problem could be not present in 2.6.24?
>>>> I have no idea there, honestly.  Sorry.
>
>> As Jon said, try 2.6.24 and see if it has an issue, if so we can look
>> at helping.  if not, you know you need to back port the fixes.
>
>> - k
>
> I've "backported" the PCI-Express code from 2.6.24 to 2.6.18, but it
> still doesn't work, I have the same problem (sigh), could you give me
> any suggestions?

did 2.6.24 work for you or not?

- k

^ permalink raw reply

* [PATCH] [2.6.25] [POWERPC] pasemi: register i2c devices at boot
From: Olof Johansson @ 2008-02-21  2:25 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, pasemi-linux

Setup i2c_board_info based on device tree contents. This has to be
a device_initcall since we need PCI to be probed by the time we
run it, but before the actual driver is initialized.


Signed-off-by: Olof Johansson <olof@lixom.net>


---

This patch was posted previously, but not merged (by myself) then because
Jon Smirl was working on his automatic probing of i2c devices. There
were also some comments to the fact that it should be made common between
the fsl_soc and pasemi platforms.

This time I'm posting it for inclusion in 2.6.25, because Jon's work has
been delayed to .26, and this is really needed for basic functionality on
the pasemi platform (i.e. to get the RTC probed properly). I expect this
to be removed once Jon's work is in, but until then it is needed. I also
don't see any need for extra churn of common code to abstract out the
fsl_soc i2c_board_info building for the same reason: this is throw-away
temporary code.

Paul, please apply for 2.6.25.


Thanks,

Olof

Index: 2.6.25/arch/powerpc/platforms/pasemi/Makefile
===================================================================
--- 2.6.25.orig/arch/powerpc/platforms/pasemi/Makefile
+++ 2.6.25/arch/powerpc/platforms/pasemi/Makefile
@@ -1,3 +1,3 @@
-obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o
+obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o misc.o
 obj-$(CONFIG_PPC_PASEMI_MDIO)	+= gpio_mdio.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
Index: 2.6.25/arch/powerpc/platforms/pasemi/misc.c
===================================================================
--- /dev/null
+++ 2.6.25/arch/powerpc/platforms/pasemi/misc.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 PA Semi, Inc
+ *
+ * Parts based on arch/powerpc/sysdev/fsl_soc.c:
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/i2c.h>
+
+#ifdef CONFIG_I2C_BOARDINFO
+/* The below is from fsl_soc.c.  It's copied because since there are no
+ * official bus bindings at this time it doesn't make sense to share across
+ * the platforms, even though they happen to be common.
+ */
+struct i2c_driver_device {
+	char    *of_device;
+	char    *i2c_driver;
+	char    *i2c_type;
+};
+
+static struct i2c_driver_device i2c_devices[] __initdata = {
+	{"dallas,ds1338",  "rtc-ds1307",  "ds1338"},
+};
+
+static int __init find_i2c_driver(struct device_node *node,
+				     struct i2c_board_info *info)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
+		if (!of_device_is_compatible(node, i2c_devices[i].of_device))
+			continue;
+		if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
+			    KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
+		    strlcpy(info->type, i2c_devices[i].i2c_type,
+			    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
+			return -ENOMEM;
+		return 0;
+	}
+	return -ENODEV;
+}
+
+static int __init pasemi_register_i2c_devices(void)
+{
+	struct pci_dev *pdev;
+	struct device_node *adap_node;
+	struct device_node *node;
+
+	pdev = NULL;
+	while ((pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa003, pdev))) {
+		adap_node = pci_device_to_OF_node(pdev);
+
+		if (!adap_node)
+			continue;
+
+		node = NULL;
+		while ((node = of_get_next_child(adap_node, node))) {
+			struct i2c_board_info info = {};
+			const u32 *addr;
+			int len;
+
+			addr = of_get_property(node, "reg", &len);
+			if (!addr || len < sizeof(int) ||
+			    *addr > (1 << 10) - 1) {
+				printk(KERN_WARNING
+					"pasemi_register_i2c_devices: "
+					"invalid i2c device entry\n");
+				continue;
+			}
+
+			info.irq = irq_of_parse_and_map(node, 0);
+			if (info.irq == NO_IRQ)
+				info.irq = -1;
+
+			if (find_i2c_driver(node, &info) < 0)
+				continue;
+
+			info.addr = *addr;
+
+			i2c_register_board_info(PCI_FUNC(pdev->devfn), &info,
+						1);
+		}
+	}
+	return 0;
+}
+device_initcall(pasemi_register_i2c_devices);
+#endif

^ permalink raw reply

* RE: Problems with plb_temac+hard_temac+2.6.24rc3
From: Rick Moleres @ 2008-02-21  2:26 UTC (permalink / raw)
  To: A. Nolson, linuxppc-embedded
In-Reply-To: <47BC563D.4040003@gmail.com>


Try using hard_temac_v3_00_a with the ML403 board.  There's an
incompatibility (posted previously on this list) with PHY access.  This
could be causing the strange behavior you're seeing.

-Rick

-----Original Message-----
From: linuxppc-embedded-bounces+moleres=3Dxilinx.com@ozlabs.org
[mailto:linuxppc-embedded-bounces+moleres=3Dxilinx.com@ozlabs.org] On
Behalf Of A. Nolson
Sent: Wednesday, February 20, 2008 8:33 AM
To: linuxppc-embedded@ozlabs.org
Subject: Problems with plb_temac+hard_temac+2.6.24rc3

Hi,

 I am working with a ML403 platform and I have my kernel 2.6.24rc3=20
perfectly running on it. Almost everything seems to work but the=20
ethernet. I am using the IP cores that come with the EDK 9.1sp2 (=20
plb_emac 3.00a + hard_temac 3.00b). The weird thing arises when I try to

bring up the interface and use it. If I do "ifconfig eth0 up" the=20
interface shows up but, strangely, it eithers not receives or send=20
packets. I will explain myself, if I assing an IP manually and try to=20
connect to another worksatation within the network ( by pinging from=20
just one of the sides  for example ) the interface seems only to send or

receive packets , but generallty not both at the same time ( I can see=20
this through the evolution of the Rx/Tx bytes in ifconfig). The only few

times that both tx/rx work at the same time is when I do (ifconfig eth0=20
down and ifconfig eth0 up), but this only works sporadically and only =20
for around a second or less.

This is what I get after the first "ifconfig eth0 up":
[  293.258765] eth0: XTemac: Options: 0xb8f2

[  295.253048] eth0: XTemac: speed set to 10Mb/s

[  295.256042] eth0: XTemac: Send Threshold =3D 16, Receive Threshold =
=3D 2

[  295.256095] eth0: XTemac: Send Wait bound =3D 1, Receive Wait bound =
=3D 1

[  297.252047] eth0: XTemac: PHY Link carrier lost.

[  299.251657] eth0: XTemac: PHY Link carrier restored.


and this after some ifconfig up/down:

[  293.258765] eth0: XTemac: Options: 0xb8f2

[  295.253048] eth0: XTemac: speed set to 10Mb/s

[  295.256042] eth0: XTemac: Send Threshold =3D 16, Receive Threshold =
=3D 2

[  295.256095] eth0: XTemac: Send Wait bound =3D 1, Receive Wait bound =
=3D 1

[  297.252047] eth0: XTemac: PHY Link carrier lost.

[  299.251657] eth0: XTemac: PHY Link carrier restored.

[  438.159833] eth0: XTemac: Options: 0xb8f2

[  440.154122] eth0: XTemac: speed set to 1000Mb/s

[  440.157316] eth0: XTemac: Send Threshold =3D 16, Receive Threshold =
=3D 2

[  440.157369] eth0: XTemac: Send Wait bound =3D 1, Receive Wait bound =
=3D 1

[  442.153739] eth0: XTemac: PHY Link carrier lost.

[  511.255518] eth0: XTemac: Options: 0xb8f2

[  513.249808] eth0: XTemac: speed set to 10Mb/s

[  513.252729] eth0: XTemac: Send Threshold =3D 16, Receive Threshold =
=3D 2

[  513.252784] eth0: XTemac: Send Wait bound =3D 1, Receive Wait bound =
=3D 1

[  515.249462] eth0: XTemac: PHY Link carrier restored.

[  992.441619] eth0: XTemac: Options: 0xb8f2

[  994.435904] eth0: XTemac: speed set to 1000Mb/s

[  994.438786] eth0: XTemac: Send Threshold =3D 16, Receive Threshold =
=3D 2

[  994.438839] eth0: XTemac: Send Wait bound =3D 1, Receive Wait bound =
=3D 1

[  996.435460] eth0: XTemac: PHY Link carrier lost.

[ 1099.850622] eth0: XTemac: Options: 0xb8f2

[ 1101.844907] eth0: XTemac: speed set to 10Mb/s

[ 1101.847816] eth0: XTemac: Send Threshold =3D 16, Receive Threshold =
=3D 2

[ 1101.847868] eth0: XTemac: Send Wait bound =3D 1, Receive Wait bound =
=3D 1

[ 1103.844479] eth0: XTemac: PHY Link carrier restored.

[ 1180.024979] eth0: XTemac: Options: 0xb8f2

[ 1182.019263] eth0: XTemac: speed set to 1000Mb/s

[ 1182.022265] eth0: XTemac: Send Threshold =3D 16, Receive Threshold =
=3D 2

[ 1182.022316] eth0: XTemac: Send Wait bound =3D 1, Receive Wait bound =
=3D 1

[ 1184.018815] eth0: XTemac: PHY Link carrier lost.


It also seems to negotiate wrongly the speed since my network is
100Mb/s.

This is my dmesg before "ifconfig eth0 up":

[    0.000000] Linux version 2.6.24-rc3-gd7ed933b-dirty (ios@xxx) (gcc=20
versio
ion 4.0.0 (DENX ELDK 4.1 4.0.0)) #17 Mon Feb 18 11:52:47 CET=20
2008               [
[    0.000000] Xilinx ML403 Reference System (Virtex-4=20
FX)                      [
[    0.000000] Entering add_active_range(0, 0, 16384) 0 entries of 256=20
used     [
[    0.000000] Zone PFN=20
ranges:                                                 [
[    0.000000]   DMA             0 ->   =20
16384                                  [
[    0.000000]   Normal      16384 ->   =20
16384                                  [
[    0.000000]   HighMem     16384 ->   =20
16384                                  [
[    0.000000] Movable zone start PFN for each=20
node                             [
[    0.000000] early_node_map[1] active PFN=20
ranges                              [
[    0.000000]     0:        0 ->   =20
16384                                      [
[    0.000000] On node 0 totalpages:=20
16384                                      [
[    0.000000]   DMA zone: 128 pages used for=20
memmap                            [
[    0.000000]   DMA zone: 0 pages=20
reserved                                     [
[    0.000000]   DMA zone: 16256 pages, LIFO=20
batch:3                            [
[    0.000000]   Normal zone: 0 pages used for=20
memmap                           [
[    0.000000]   HighMem zone: 0 pages used for=20
memmap                          [
[    0.000000]   Movable zone: 0 pages used for=20
memmap                          [
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on. =20
Total pages
es:=20
16256

[
[    0.000000] Kernel command line: console=3DttyS0,57600 =
root=3D/dev/xsa2=20
rw init=3D/sb
sbin/init

[
[    0.000000] Xilinx INTC #0 at 0x41200000 mapped to=20
0xFDFFE000                [
[    0.000000] PID hash table entries: 256 (order: 8, 1024=20
bytes)               [
[    0.000189] Console: colour dummy device=20
80x25                               [
[    0.000632] Dentry cache hash table entries: 8192 (order: 3, 32768=20
bytes)    [
[    0.001411] Inode-cache hash table entries: 4096 (order: 2, 16384=20
bytes)     [
[    0.015628] Memory: 61312k available (2744k kernel code, 780k data,=20
116k init,
, 0k=20
highmem)

[
[    0.015942] SLUB: Genslabs=3D11, HWalign=3D32, Order=3D0-1, =
MinObjects=3D4,=20
CPUs=3D1, Nod
odes=3D1

[
[    0.015988] Calibrating delay loop... 199.47 BogoMIPS=20
(lpj=3D997376)           [
[    0.210274] Mount-cache hash table entries:=20
512                              [
[    0.214569] net_namespace: 64=20
bytes                                          [
[    0.220610] NET: Registered protocol family=20
16                               [
[    0.268325] NET: Registered protocol family=20
2                                [
[    0.350699] IP route cache hash table entries: 1024 (order: 0, 4096=20
bytes)   [
[    0.353529] TCP established hash table entries: 2048 (order: 2, 16384

bytes) [
[    0.353862] TCP bind hash table entries: 2048 (order: 1, 8192=20
bytes)         [
[    0.354067] TCP: Hash tables configured (established 2048 bind=20
2048)         [
[    0.354107] TCP reno=20
registered                                              [
[    0.381445] sysctl table check failed: /kernel/l2cr .1.31 Missing=20
strategy   [
[    0.381529] Call=20
Trace:                                                      [
[    0.381556] [c3c11e80] [c0008380] show_stack+0x4c/0x174=20
(unreliable)         [
[    0.381653] [c3c11eb0] [c0037170]=20
set_fail+0x50/0x68                         [
[    0.381735] [c3c11ed0] [c00377f8]=20
sysctl_check_table+0x670/0x6bc             [
[    0.381804] [c3c11f10] [c003780c]=20
sysctl_check_table+0x684/0x6bc             [
[    0.381871] [c3c11f50] [c0024e7c]=20
register_sysctl_table+0x5c/0xac            [
[    0.381953] [c3c11f70] [c034ab68]=20
register_ppc_htab_sysctl+0x18/0x2c         [
[    0.382040] [c3c11f80] [c034484c]=20
kernel_init+0xc8/0x284                     [
[    0.382103] [c3c11ff0] [c0004b18]=20
kernel_thread+0x44/0x60                    [
[    0.442249] Installing knfsd (copyright (C) 1996=20
okir@monad.swb.de).         [
[    0.447391] JFS: nTxBlock =3D 479, nTxLock =3D=20
3832                              [
[    0.450534] SGI XFS with ACLs, large block numbers, no debug=20
enabled         [
[    0.466636] io scheduler noop=20
registered                                     [
[    0.466687] io scheduler anticipatory=20
registered                             [
[    0.466722] io scheduler deadline=20
registered                                 [
[    0.467224] io scheduler cfq registered=20
(default)                            [
[    1.069672] Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ=20
sharing di
disabled

[
[    1.078357] serial8250.0: ttyS0 at MMIO 0x40401003 (irq =3D 3) is a=20
16550A     [
[    1.078443] console [ttyS0]=20
enabled                                          [
[    1.621990] RAMDISK driver initialized: 16 RAM disks of 4096K size=20
1024 blocksi
size

[
[    1.644429] loop: module=20
loaded                                              [
[    1.651930] xsysace xsysace.0: Xilinx SystemACE revision=20
1.0.12              [
[    1.664582] xsysace xsysace.0: capacity: 1019088=20
sectors                     [
[    1.675836]  xsa: xsa1 xsa2=20
xsa3                                             [
[    1.688906] Xilinx SystemACE device driver,=20
major=3D254                        [
[    1.700197] nbd: registered device at major=20
43                               [
[    1.728380] XTemac: using sgDMA=20
mode.                                        [
[    1.735840] XTemac: using TxDRE=20
mode                                         [
[    1.743198] XTemac: using RxDRE=20
mode                                         [
[    1.750455] XTemac: buffer descriptor size: 32768=20
(0x8000)                   [
[    1.762007] XTemac: (buffer_descriptor_init) phy: 0x3d98000, virt:=20
0xff100000,
, size:=20
0x8000
[
[    1.785641] eth%d: XTemac: No PHY detected.  Assuming a PHY at=20
address 0     [
[    1.799277] eth0: Dropping NETIF_F_SG since no checksum=20
feature.             [
[    1.814696] eth0: Xilinx TEMAC #0 at 0x81200000 mapped to 0xC5060000,

irq=3D0  [
[    1.828792] eth0: XTemac id 1.0f, block id 5, type=20
8                         [
[    1.840200] NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c=20
$Revision: 1
 1.41=20
$
[
[    1.856295] INFTL: inftlcore.c $Revision: 1.19 $, inftlmount.c=20
$Revision: 1.18
8=20
$

[
[    1.872015] SSFDC read-only Flash Translation=20
layer                          [
[    1.885404] i8042.c: No controller=20
found.                                    [
[    1.895700] mice: PS/2 mouse device common for all=20
mice                      [
[    1.908819] i2c /dev entries=20
driver                                          [
[    1.917372] TCP cubic=20
registered                                             [
[    1.924238] NET: Registered protocol family=20
1                                [
[    1.933271] NET: Registered protocol family=20
17                               [
[    1.944649] RPC: Registered udp transport=20
module.                            [
[    1.954206] RPC: Registered tcp transport=20
module.                            [
[    4.575003] kjournald starting.  Commit interval 5=20
seconds                   [
[    4.586220] EXT3-fs warning: maximal mount count reached, running=20
e2fsck is rec
ecommended

[
[    4.641727] EXT3 FS on xsa2, internal=20
journal                                [
[    4.650587] EXT3-fs: recovery=20
complete.                                      [
[    4.697624] EXT3-fs: mounted filesystem with ordered data=20
mode.              [
[    4.709702] VFS: Mounted root (ext3=20
filesystem).                             [
[    4.719390] Freeing unused kernel memory: 116k=20
init                         =20
ba                                                             =20

Any idea of what it can be?

Thanks in advance!

/A
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded

^ permalink raw reply

* [PATCH] [POWERPC] pasemi: remove warning in mpic_pasemi_msi.c
From: Olof Johansson @ 2008-02-21  2:34 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, pasemi-linux

Remove warning:

arch/powerpc/sysdev/mpic_pasemi_msi.c: In function 'pasemi_msi_setup_msi_irqs':
arch/powerpc/sysdev/mpic_pasemi_msi.c:135: warning: 'addr' is used uninitialized in this function

Turns out addr wasn't even used, it's a leftover from the u3msi code.

Signed-off-by: Olof Johansson <olof@lixom.net>


diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index d6bfda3..33cbfb2 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -95,7 +95,6 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 	unsigned int virq;
 	struct msi_desc *entry;
 	struct msi_msg msg;
-	u64 addr;
 
 	pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n",
 		 pdev, nvec, type);
@@ -132,8 +131,8 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 		set_irq_chip(virq, &mpic_pasemi_msi_chip);
 		set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
 
-		pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n",
-			  virq, hwirq, addr);
+		pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%x\n",
+			  virq, hwirq, msg.address_lo);
 
 		/* Likewise, the device writes [0...511] into the target
 		 * register to generate MSI [512...1023]

^ permalink raw reply related

* [patch 0/6] pasemi_mac updates for 2.6.26
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

Here's a set of updates for pasemi_mac for 2.6.26. Some of them touch
the dma_lib in the platform code as well, but it's easier if it's all
merged through netdev to avoid dependencies.

Major highlights are jumbo frame support and ethtool basics, the rest
is mostly minor plumbing around it.

-- 

^ permalink raw reply

* [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev
In-Reply-To: <20080221025753.903665000@lixom.net>

Also stop both rx and tx sections before changing the configuration of
the dma device during init.

Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/dma_lib.c
+++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -478,6 +478,30 @@ int pasemi_dma_init(void)
 	for (i = 0; i < MAX_RXCH; i++)
 		__set_bit(i, rxch_free);
 
+	i = 1000;
+	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
+	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1))
+		i--;
+	if (i < 0)
+		printk(KERN_INFO "Warning: Could not disable RX section\n");
+
+	i = 1000;
+	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
+	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1))
+		i--;
+	if (i < 0)
+		printk(KERN_INFO "Warning: Could not disable TX section\n");
+
+	/* setup resource allocations for the different DMA sections */
+	tmp = pasemi_read_dma_reg(PAS_DMA_COM_CFG);
+	pasemi_write_dma_reg(PAS_DMA_COM_CFG, tmp | 0x18000000);
+
+	/* enable tx section */
+	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
+
+	/* enable rx section */
+	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
+
 	printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
 		"(%d tx, %d rx channels)\n", num_txch, num_rxch);
 
Index: k.org/drivers/net/pasemi_mac.c
===================================================================
--- k.org.orig/drivers/net/pasemi_mac.c
+++ k.org/drivers/net/pasemi_mac.c
@@ -1043,12 +1043,6 @@ static int pasemi_mac_open(struct net_de
 	unsigned int flags;
 	int ret;
 
-	/* enable rx section */
-	write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
-
-	/* enable tx section */
-	write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
-
 	flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
 		PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
 		PAS_MAC_CFG_TXP_TIFT(8) | PAS_MAC_CFG_TXP_TIFG(12);
Index: k.org/include/asm-powerpc/pasemi_dma.h
===================================================================
--- k.org.orig/include/asm-powerpc/pasemi_dma.h
+++ k.org/include/asm-powerpc/pasemi_dma.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 PA Semi, Inc
+ * Copyright (C) 2006-2008 PA Semi, Inc
  *
  * Hardware register layout and descriptor formats for the on-board
  * DMA engine on PA Semi PWRficient. Used by ethernet, function and security
@@ -40,6 +40,11 @@ enum {
 	PAS_DMA_COM_TXSTA = 0x104,	/* Transmit Status Register   */
 	PAS_DMA_COM_RXCMD = 0x108,	/* Receive Command Register   */
 	PAS_DMA_COM_RXSTA = 0x10c,	/* Receive Status Register    */
+	PAS_DMA_COM_CFG   = 0x114,	/* Common config reg	      */
+	PAS_DMA_TXF_SFLG0 = 0x140,	/* Set flags                  */
+	PAS_DMA_TXF_SFLG1 = 0x144,	/* Set flags                  */
+	PAS_DMA_TXF_CFLG0 = 0x148,	/* Set flags                  */
+	PAS_DMA_TXF_CFLG1 = 0x14c,	/* Set flags                  */
 };
 
 

-- 

^ permalink raw reply

* [patch 2/6] [POWERPC] pasemi: Add flag management functions to dma_lib
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev
In-Reply-To: <20080221025753.903665000@lixom.net>

Add functions to manage the channel syncronization flags to dma_lib
    
Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/dma_lib.c
+++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -26,6 +26,7 @@
 
 #define MAX_TXCH 64
 #define MAX_RXCH 64
+#define MAX_FLAGS 64
 
 static struct pasdma_status *dma_status;
 
@@ -43,6 +44,7 @@ static struct pci_dev *dma_pdev;
 
 static DECLARE_BITMAP(txch_free, MAX_TXCH);
 static DECLARE_BITMAP(rxch_free, MAX_RXCH);
+static DECLARE_BITMAP(flags_free, MAX_FLAGS);
 
 /* pasemi_read_iob_reg - read IOB register
  * @reg: Register to read (offset into PCI CFG space)
@@ -373,6 +375,71 @@ void pasemi_dma_free_buf(struct pasemi_d
 }
 EXPORT_SYMBOL(pasemi_dma_free_buf);
 
+/* pasemi_dma_alloc_flag - Allocate a flag (event) for channel syncronization
+ *
+ * Allocates a flag for use with channel syncronization (event descriptors).
+ * Returns allocated flag (0-63), < 0 on error.
+ */
+int pasemi_dma_alloc_flag(void)
+{
+	int bit;
+
+retry:
+	bit = find_next_bit(flags_free, MAX_FLAGS, 0);
+	if (bit >= MAX_FLAGS)
+		return -ENOSPC;
+	if (!test_and_clear_bit(bit, flags_free))
+		goto retry;
+
+	return bit;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_flag);
+
+
+/* pasemi_dma_free_flag - Deallocates a flag (event)
+ * @flag: Flag number to deallocate
+ *
+ * Frees up a flag so it can be reused for other purposes.
+ */
+void pasemi_dma_free_flag(int flag)
+{
+	BUG_ON(test_bit(flag, flags_free));
+	BUG_ON(flag >= MAX_FLAGS);
+	set_bit(flag, flags_free);
+}
+EXPORT_SYMBOL(pasemi_dma_free_flag);
+
+
+/* pasemi_dma_set_flag - Sets a flag (event) to 1
+ * @flag: Flag number to set active
+ *
+ * Sets the flag provided to 1.
+ */
+void pasemi_dma_set_flag(int flag)
+{
+	BUG_ON(flag >= MAX_FLAGS);
+	if (flag < 32)
+		pasemi_write_dma_reg(PAS_DMA_TXF_SFLG0, 1 << flag);
+	else
+		pasemi_write_dma_reg(PAS_DMA_TXF_SFLG1, 1 << flag);
+}
+EXPORT_SYMBOL(pasemi_dma_set_flag);
+
+/* pasemi_dma_clear_flag - Sets a flag (event) to 0
+ * @flag: Flag number to set inactive
+ *
+ * Sets the flag provided to 0.
+ */
+void pasemi_dma_clear_flag(int flag)
+{
+	BUG_ON(flag >= MAX_FLAGS);
+	if (flag < 32)
+		pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 1 << flag);
+	else
+		pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 1 << flag);
+}
+EXPORT_SYMBOL(pasemi_dma_clear_flag);
+
 static void *map_onedev(struct pci_dev *p, int index)
 {
 	struct device_node *dn;
@@ -502,6 +569,13 @@ int pasemi_dma_init(void)
 	/* enable rx section */
 	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
 
+	for (i = 0; i < MAX_FLAGS; i++)
+		__set_bit(i, flags_free);
+
+	/* clear all status flags */
+	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff);
+	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff);
+
 	printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
 		"(%d tx, %d rx channels)\n", num_txch, num_rxch);
 
Index: k.org/include/asm-powerpc/pasemi_dma.h
===================================================================
--- k.org.orig/include/asm-powerpc/pasemi_dma.h
+++ k.org/include/asm-powerpc/pasemi_dma.h
@@ -466,6 +466,12 @@ extern void *pasemi_dma_alloc_buf(struct
 extern void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
 				dma_addr_t *handle);
 
+/* Routines to allocate flags (events) for channel syncronization */
+extern int  pasemi_dma_alloc_flag(void);
+extern void pasemi_dma_free_flag(int flag);
+extern void pasemi_dma_set_flag(int flag);
+extern void pasemi_dma_clear_flag(int flag);
+
 /* Initialize the library, must be called before any other functions */
 extern int pasemi_dma_init(void);
 

-- 

^ permalink raw reply

* [patch 3/6] [POWERPC] pasemi: Add function engine management functions to dma_lib
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev
In-Reply-To: <20080221025753.903665000@lixom.net>

Used to allocate functions for crypto/checksum offload.
    
Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/dma_lib.c
+++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -27,6 +27,7 @@
 #define MAX_TXCH 64
 #define MAX_RXCH 64
 #define MAX_FLAGS 64
+#define MAX_FUN 8
 
 static struct pasdma_status *dma_status;
 
@@ -45,6 +46,7 @@ static struct pci_dev *dma_pdev;
 static DECLARE_BITMAP(txch_free, MAX_TXCH);
 static DECLARE_BITMAP(rxch_free, MAX_RXCH);
 static DECLARE_BITMAP(flags_free, MAX_FLAGS);
+static DECLARE_BITMAP(fun_free, MAX_FUN);
 
 /* pasemi_read_iob_reg - read IOB register
  * @reg: Register to read (offset into PCI CFG space)
@@ -440,6 +442,41 @@ void pasemi_dma_clear_flag(int flag)
 }
 EXPORT_SYMBOL(pasemi_dma_clear_flag);
 
+/* pasemi_dma_alloc_fun - Allocate a function engine
+ *
+ * Allocates a function engine to use for crypto/checksum offload
+ * Returns allocated engine (0-8), < 0 on error.
+ */
+int pasemi_dma_alloc_fun(void)
+{
+	int bit;
+
+retry:
+	bit = find_next_bit(fun_free, MAX_FLAGS, 0);
+	if (bit >= MAX_FLAGS)
+		return -ENOSPC;
+	if (!test_and_clear_bit(bit, fun_free))
+		goto retry;
+
+	return bit;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_fun);
+
+
+/* pasemi_dma_free_fun - Deallocates a function engine
+ * @flag: Engine number to deallocate
+ *
+ * Frees up a function engine so it can be used for other purposes.
+ */
+void pasemi_dma_free_fun(int fun)
+{
+	BUG_ON(test_bit(fun, fun_free));
+	BUG_ON(fun >= MAX_FLAGS);
+	set_bit(fun, fun_free);
+}
+EXPORT_SYMBOL(pasemi_dma_free_fun);
+
+
 static void *map_onedev(struct pci_dev *p, int index)
 {
 	struct device_node *dn;
@@ -572,6 +609,9 @@ int pasemi_dma_init(void)
 	for (i = 0; i < MAX_FLAGS; i++)
 		__set_bit(i, flags_free);
 
+	for (i = 0; i < MAX_FUN; i++)
+		__set_bit(i, fun_free);
+
 	/* clear all status flags */
 	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff);
 	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff);
Index: k.org/include/asm-powerpc/pasemi_dma.h
===================================================================
--- k.org.orig/include/asm-powerpc/pasemi_dma.h
+++ k.org/include/asm-powerpc/pasemi_dma.h
@@ -472,6 +472,10 @@ extern void pasemi_dma_free_flag(int fla
 extern void pasemi_dma_set_flag(int flag);
 extern void pasemi_dma_clear_flag(int flag);
 
+/* Routines to allocate function engines */
+extern int  pasemi_dma_alloc_fun(void);
+extern void pasemi_dma_free_fun(int fun);
+
 /* Initialize the library, must be called before any other functions */
 extern int pasemi_dma_init(void);
 

-- 

^ permalink raw reply

* [patch 4/6] pasemi_mac: jumbo frame support
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev
In-Reply-To: <20080221025753.903665000@lixom.net>

First cut at jumbo frame support. To support large MTU, one or several
separate channels must be allocated to calculate the TCP/UDP checksum
separately, since the mac lacks enough buffers to hold a whole packet
while it's being calculated.

Furthermore, it seems that a single function channel is not quite
enough to feed one of the 10Gig links, so allocate two channels for
XAUI interfaces.

Signed-off-by: Olof Johansson <olof@lixom.net>

Index: 2.6.25/drivers/net/pasemi_mac.c
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.c
+++ 2.6.25/drivers/net/pasemi_mac.c
@@ -59,11 +59,12 @@
 /* Must be a power of two */
 #define RX_RING_SIZE 2048
 #define TX_RING_SIZE 4096
+#define CS_RING_SIZE (TX_RING_SIZE*2)
 
 #define LRO_MAX_AGGR 64
 
 #define PE_MIN_MTU	64
-#define PE_MAX_MTU	1500
+#define PE_MAX_MTU	9000
 #define PE_DEF_MTU	ETH_DATA_LEN
 
 #define DEFAULT_MSG_ENABLE	  \
@@ -81,6 +82,7 @@
 #define RX_DESC(rx, num)	((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
 #define RX_DESC_INFO(rx, num)	((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
 #define RX_BUFF(rx, num)	((rx)->buffers[(num) & (RX_RING_SIZE-1)])
+#define CS_DESC(cs, num)	((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)])
 
 #define RING_USED(ring)		(((ring)->next_to_fill - (ring)->next_to_clean) \
 				 & ((ring)->size - 1))
@@ -322,6 +324,103 @@ static int pasemi_mac_unmap_tx_skb(struc
 	return (nfrags + 3) & ~1;
 }
 
+static struct pasemi_mac_csring *pasemi_mac_setup_csring(struct pasemi_mac *mac)
+{
+	struct pasemi_mac_csring *ring;
+	u32 val;
+	unsigned int cfg;
+	int chno;
+
+	ring = pasemi_dma_alloc_chan(TXCHAN, sizeof(struct pasemi_mac_csring),
+				       offsetof(struct pasemi_mac_csring, chan));
+
+	if (!ring) {
+		dev_err(&mac->pdev->dev, "Can't allocate checksum channel\n");
+		goto out_chan;
+	}
+
+	chno = ring->chan.chno;
+
+	ring->size = CS_RING_SIZE;
+	ring->next_to_fill = 0;
+
+	/* Allocate descriptors */
+	if (pasemi_dma_alloc_ring(&ring->chan, CS_RING_SIZE))
+		goto out_ring_desc;
+
+	write_dma_reg(PAS_DMA_TXCHAN_BASEL(chno),
+		      PAS_DMA_TXCHAN_BASEL_BRBL(ring->chan.ring_dma));
+	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32);
+	val |= PAS_DMA_TXCHAN_BASEU_SIZ(CS_RING_SIZE >> 3);
+
+	write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val);
+
+	ring->events[0] = pasemi_dma_alloc_flag();
+	ring->events[1] = pasemi_dma_alloc_flag();
+	if (ring->events[0] < 0 || ring->events[1] < 0)
+		goto out_flags;
+
+	pasemi_dma_clear_flag(ring->events[0]);
+	pasemi_dma_clear_flag(ring->events[1]);
+
+	ring->fun = pasemi_dma_alloc_fun();
+	if (ring->fun < 0)
+		goto out_fun;
+
+	cfg = PAS_DMA_TXCHAN_CFG_TY_FUNC | PAS_DMA_TXCHAN_CFG_UP |
+	      PAS_DMA_TXCHAN_CFG_TATTR(ring->fun) |
+	      PAS_DMA_TXCHAN_CFG_LPSQ | PAS_DMA_TXCHAN_CFG_LPDQ;
+
+	if (translation_enabled())
+		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
+
+	write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg);
+
+	/* enable channel */
+	pasemi_dma_start_chan(&ring->chan, PAS_DMA_TXCHAN_TCMDSTA_SZ |
+					   PAS_DMA_TXCHAN_TCMDSTA_DB |
+					   PAS_DMA_TXCHAN_TCMDSTA_DE |
+					   PAS_DMA_TXCHAN_TCMDSTA_DA);
+
+	return ring;
+
+out_fun:
+out_flags:
+	if (ring->events[0] >= 0)
+		pasemi_dma_free_flag(ring->events[0]);
+	if (ring->events[1] >= 0)
+		pasemi_dma_free_flag(ring->events[1]);
+	pasemi_dma_free_ring(&ring->chan);
+out_ring_desc:
+	pasemi_dma_free_chan(&ring->chan);
+out_chan:
+
+	return NULL;
+}
+
+static void pasemi_mac_setup_csrings(struct pasemi_mac *mac)
+{
+	int i;
+	mac->cs[0] = pasemi_mac_setup_csring(mac);
+	if (mac->type == MAC_TYPE_XAUI)
+		mac->cs[1] = pasemi_mac_setup_csring(mac);
+	else
+		mac->cs[1] = 0;
+
+	for (i = 0; i < MAX_CS; i++)
+		if (mac->cs[i])
+			mac->num_cs++;
+}
+
+static void pasemi_mac_free_csring(struct pasemi_mac_csring *csring)
+{
+	pasemi_dma_stop_chan(&csring->chan);
+	pasemi_dma_free_flag(csring->events[0]);
+	pasemi_dma_free_flag(csring->events[1]);
+	pasemi_dma_free_ring(&csring->chan);
+	pasemi_dma_free_chan(&csring->chan);
+}
+
 static int pasemi_mac_setup_rx_resources(const struct net_device *dev)
 {
 	struct pasemi_mac_rxring *ring;
@@ -445,7 +544,7 @@ pasemi_mac_setup_tx_resources(const stru
 	cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
 	      PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
 	      PAS_DMA_TXCHAN_CFG_UP |
-	      PAS_DMA_TXCHAN_CFG_WT(2);
+	      PAS_DMA_TXCHAN_CFG_WT(4);
 
 	if (translation_enabled())
 		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
@@ -810,13 +909,21 @@ restart:
 		u64 mactx = TX_DESC(txring, i);
 		struct sk_buff *skb;
 
-		skb = TX_DESC_INFO(txring, i+1).skb;
-		nr_frags = TX_DESC_INFO(txring, i).dma;
-
 		if ((mactx  & XCT_MACTX_E) ||
 		    (*chan->status & PAS_STATUS_ERROR))
 			pasemi_mac_tx_error(mac, mactx);
 
+		/* Skip over control descriptors */
+		if (!(mactx & XCT_MACTX_LLEN_M)) {
+			TX_DESC(txring, i) = 0;
+			TX_DESC(txring, i+1) = 0;
+			buf_count = 2;
+			continue;
+		}
+
+		skb = TX_DESC_INFO(txring, i+1).skb;
+		nr_frags = TX_DESC_INFO(txring, i).dma;
+
 		if (unlikely(mactx & XCT_MACTX_O))
 			/* Not yet transmitted */
 			break;
@@ -1058,6 +1165,12 @@ static int pasemi_mac_open(struct net_de
 	if (!mac->tx)
 		goto out_tx_ring;
 
+	if (dev->mtu > 1500) {
+		pasemi_mac_setup_csrings(mac);
+		if (!mac->num_cs)
+			goto out_tx_ring;
+	}
+
 	/* 0x3ff with 33MHz clock is about 31us */
 	write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
 		      PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));
@@ -1241,7 +1354,7 @@ static int pasemi_mac_close(struct net_d
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int sta;
-	int rxch, txch;
+	int rxch, txch, i;
 
 	rxch = rx_ring(mac)->chan.chno;
 	txch = tx_ring(mac)->chan.chno;
@@ -1286,6 +1399,9 @@ static int pasemi_mac_close(struct net_d
 	free_irq(mac->tx->chan.irq, mac->tx);
 	free_irq(mac->rx->chan.irq, mac->rx);
 
+	for (i = 0; i < mac->num_cs; i++)
+		pasemi_mac_free_csring(mac->cs[i]);
+
 	/* Free resources */
 	pasemi_mac_free_rx_resources(mac);
 	pasemi_mac_free_tx_resources(mac);
@@ -1293,35 +1409,113 @@ static int pasemi_mac_close(struct net_d
 	return 0;
 }
 
+static void pasemi_mac_queue_csdesc(const struct sk_buff *skb,
+				    const dma_addr_t *map,
+				    const unsigned int *map_size,
+				    struct pasemi_mac_txring *txring,
+				    struct pasemi_mac_csring *csring)
+{
+	u64 fund;
+	dma_addr_t cs_dest;
+	const int nh_off = skb_network_offset(skb);
+	const int nh_len = skb_network_header_len(skb);
+	const int nfrags = skb_shinfo(skb)->nr_frags;
+	int cs_size, i, fill, hdr, cpyhdr, evt;
+	dma_addr_t csdma;
+
+	fund = XCT_FUN_ST | XCT_FUN_RR_8BRES |
+	       XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
+	       XCT_FUN_CRM_SIG | XCT_FUN_LLEN(skb->len - nh_off) |
+	       XCT_FUN_SHL(nh_len >> 2) | XCT_FUN_SE;
+
+	switch (ip_hdr(skb)->protocol) {
+	case IPPROTO_TCP:
+		fund |= XCT_FUN_SIG_TCP4;
+		/* TCP checksum is 16 bytes into the header */
+		cs_dest = map[0] + skb_transport_offset(skb) + 16;
+		break;
+	case IPPROTO_UDP:
+		fund |= XCT_FUN_SIG_UDP4;
+		/* UDP checksum is 6 bytes into the header */
+		cs_dest = map[0] + skb_transport_offset(skb) + 6;
+		break;
+	default:
+		WARN_ON(1);
+	}
+
+	/* Do the checksum offloaded */
+	fill = csring->next_to_fill;
+	hdr = fill;
+
+	CS_DESC(csring, fill++) = fund;
+	/* Room for 8BRES. Checksum result is really 2 bytes into it */
+	csdma = csring->chan.ring_dma + (fill & (CS_RING_SIZE-1)) * 8 + 2;
+	CS_DESC(csring, fill++) = 0;
+
+	CS_DESC(csring, fill) = XCT_PTR_LEN(map_size[0]-nh_off) | XCT_PTR_ADDR(map[0]+nh_off);
+	for (i = 1; i <= nfrags; i++)
+		CS_DESC(csring, fill+i) = XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
+
+	fill += i;
+	if (fill & 1)
+		fill++;
+
+	/* Copy the result into the TCP packet */
+	cpyhdr = fill;
+	CS_DESC(csring, fill++) = XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
+				  XCT_FUN_LLEN(2) | XCT_FUN_SE;
+	CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(cs_dest) | XCT_PTR_T;
+	CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(csdma);
+	fill++;
+
+	evt = !csring->last_event;
+	csring->last_event = evt;
+
+	/* Event handshaking with MAC TX */
+	CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_SET | CTRL_CMD_REG(csring->events[evt]);
+	CS_DESC(csring, fill++) = 0;
+	CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_WCLR | CTRL_CMD_REG(csring->events[!evt]);
+	CS_DESC(csring, fill++) = 0;
+	csring->next_to_fill = fill & (CS_RING_SIZE-1);
+
+	cs_size = fill - hdr;
+	write_dma_reg(PAS_DMA_TXCHAN_INCR(csring->chan.chno), (cs_size) >> 1);
+
+	/* TX-side event handshaking */
+	fill = txring->next_to_fill;
+	TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_WSET | CTRL_CMD_REG(csring->events[evt]);
+	TX_DESC(txring, fill++) = 0;
+	TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_CLR | CTRL_CMD_REG(csring->events[!evt]);
+	TX_DESC(txring, fill++) = 0;
+	txring->next_to_fill = fill;
+
+	write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2);
+
+	return;
+}
+
 static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct pasemi_mac *mac = netdev_priv(dev);
-	struct pasemi_mac_txring *txring;
-	u64 dflags, mactx;
+	struct pasemi_mac * const mac = netdev_priv(dev);
+	struct pasemi_mac_txring * const txring = tx_ring(mac);
+	struct pasemi_mac_csring *csring;
+	u64 dflags = 0;
+	u64 mactx;
 	dma_addr_t map[MAX_SKB_FRAGS+1];
 	unsigned int map_size[MAX_SKB_FRAGS+1];
 	unsigned long flags;
 	int i, nfrags;
 	int fill;
+	const int nh_off = skb_network_offset(skb);
+	const int nh_len = skb_network_header_len(skb);
 
-	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
-
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		const unsigned char *nh = skb_network_header(skb);
+	prefetch(&txring->ring_info);
 
-		switch (ip_hdr(skb)->protocol) {
-		case IPPROTO_TCP:
-			dflags |= XCT_MACTX_CSUM_TCP;
-			dflags |= XCT_MACTX_IPH(skb_network_header_len(skb) >> 2);
-			dflags |= XCT_MACTX_IPO(nh - skb->data);
-			break;
-		case IPPROTO_UDP:
-			dflags |= XCT_MACTX_CSUM_UDP;
-			dflags |= XCT_MACTX_IPH(skb_network_header_len(skb) >> 2);
-			dflags |= XCT_MACTX_IPO(nh - skb->data);
-			break;
-		}
-	}
+	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
 
 	nfrags = skb_shinfo(skb)->nr_frags;
 
@@ -1344,24 +1538,46 @@ static int pasemi_mac_start_tx(struct sk
 		}
 	}
 
-	mactx = dflags | XCT_MACTX_LLEN(skb->len);
+	if (skb->ip_summed == CHECKSUM_PARTIAL && skb->len <= 1540) {
+		switch (ip_hdr(skb)->protocol) {
+		case IPPROTO_TCP:
+			dflags |= XCT_MACTX_CSUM_TCP;
+			dflags |= XCT_MACTX_IPH(nh_len >> 2);
+			dflags |= XCT_MACTX_IPO(nh_off);
+			break;
+		case IPPROTO_UDP:
+			dflags |= XCT_MACTX_CSUM_UDP;
+			dflags |= XCT_MACTX_IPH(nh_len >> 2);
+			dflags |= XCT_MACTX_IPO(nh_off);
+			break;
+		default:
+			WARN_ON(1);
+		}
+	}
 
-	txring = tx_ring(mac);
+	mactx = dflags | XCT_MACTX_LLEN(skb->len);
 
 	spin_lock_irqsave(&txring->lock, flags);
 
-	fill = txring->next_to_fill;
-
 	/* Avoid stepping on the same cache line that the DMA controller
 	 * is currently about to send, so leave at least 8 words available.
 	 * Total free space needed is mactx + fragments + 8
 	 */
-	if (RING_AVAIL(txring) < nfrags + 10) {
+	if (RING_AVAIL(txring) < nfrags + 14) {
 		/* no room -- stop the queue and wait for tx intr */
 		netif_stop_queue(dev);
 		goto out_err;
 	}
 
+	if (mac->num_cs && skb->len > 1540) {
+		csring = mac->cs[mac->last_cs];
+		mac->last_cs = (mac->last_cs+1) % mac->num_cs;
+
+		/* Queue up checksum + event descriptors, if needed */
+		pasemi_mac_queue_csdesc(skb, map, map_size, txring, csring);
+	}
+
+	fill = txring->next_to_fill;
 	TX_DESC(txring, fill) = mactx;
 	TX_DESC_INFO(txring, fill).dma = nfrags;
 	fill++;
@@ -1441,6 +1657,7 @@ static int pasemi_mac_change_mtu(struct 
 	unsigned int reg;
 	unsigned int rcmdsta;
 	int running;
+	int ret = 0;
 
 	if (new_mtu < PE_MIN_MTU || new_mtu > PE_MAX_MTU)
 		return -EINVAL;
@@ -1462,6 +1679,16 @@ static int pasemi_mac_change_mtu(struct 
 		pasemi_mac_pause_rxint(mac);
 		pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
 		pasemi_mac_free_rx_buffers(mac);
+
+	}
+
+	/* Setup checksum channels if large MTU and none already allocated */
+	if (new_mtu > 1500 && !mac->num_cs) {
+		pasemi_mac_setup_csrings(mac);
+		if (!mac->num_cs) {
+			ret = -ENOMEM;
+			goto out;
+		}
 	}
 
 	/* Change maxf, i.e. what size frames are accepted.
@@ -1476,6 +1703,7 @@ static int pasemi_mac_change_mtu(struct 
 	/* MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
 	mac->bufsz = new_mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
 
+out:
 	if (running) {
 		write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
 			      rcmdsta | PAS_DMA_RXINT_RCMDSTA_EN);
@@ -1488,7 +1716,7 @@ static int pasemi_mac_change_mtu(struct 
 		pasemi_mac_intf_enable(mac);
 	}
 
-	return 0;
+	return ret;
 }
 
 static int __devinit
Index: 2.6.25/drivers/net/pasemi_mac.h
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.h
+++ 2.6.25/drivers/net/pasemi_mac.h
@@ -27,6 +27,7 @@
 #include <linux/phy.h>
 
 #define MAX_LRO_DESCRIPTORS 8
+#define MAX_CS	2
 
 struct pasemi_mac_txring {
 	struct pasemi_dmachan chan; /* Must be first */
@@ -51,6 +52,15 @@ struct pasemi_mac_rxring {
 	struct pasemi_mac *mac;	/* Needed in intr handler */
 };
 
+struct pasemi_mac_csring {
+	struct pasemi_dmachan chan;
+	unsigned int	size;
+	unsigned int	next_to_fill;
+	int		events[2];
+	int		last_event;
+	int		fun;
+};
+
 struct pasemi_mac {
 	struct net_device *netdev;
 	struct pci_dev *pdev;
@@ -60,10 +70,12 @@ struct pasemi_mac {
 	struct napi_struct napi;
 
 	int		bufsz; /* RX ring buffer size */
+	int		last_cs;
+	int		num_cs;
+	u32		dma_if;
 	u8		type;
 #define MAC_TYPE_GMAC	1
 #define MAC_TYPE_XAUI	2
-	u32	dma_if;
 
 	u8		mac_addr[6];
 
@@ -74,6 +86,7 @@ struct pasemi_mac {
 
 	struct pasemi_mac_txring *tx;
 	struct pasemi_mac_rxring *rx;
+	struct pasemi_mac_csring *cs[MAX_CS];
 	char		tx_irq_name[10];		/* "eth%d tx" */
 	char		rx_irq_name[10];		/* "eth%d rx" */
 	int	link;
Index: 2.6.25/include/asm-powerpc/pasemi_dma.h
===================================================================
--- 2.6.25.orig/include/asm-powerpc/pasemi_dma.h
+++ 2.6.25/include/asm-powerpc/pasemi_dma.h
@@ -128,11 +128,16 @@ enum {
 #define    PAS_DMA_TXCHAN_TCMDSTA_DA	0x00000100
 #define PAS_DMA_TXCHAN_CFG(c)     (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
 #define    PAS_DMA_TXCHAN_CFG_TY_IFACE	0x00000000	/* Type = interface */
+#define    PAS_DMA_TXCHAN_CFG_TY_COPY	0x00000001	/* Type = copy only */
+#define    PAS_DMA_TXCHAN_CFG_TY_FUNC	0x00000002	/* Type = function */
+#define    PAS_DMA_TXCHAN_CFG_TY_XOR	0x00000003	/* Type = xor only */
 #define    PAS_DMA_TXCHAN_CFG_TATTR_M	0x0000003c
 #define    PAS_DMA_TXCHAN_CFG_TATTR_S	2
 #define    PAS_DMA_TXCHAN_CFG_TATTR(x)	(((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
 					 PAS_DMA_TXCHAN_CFG_TATTR_M)
-#define    PAS_DMA_TXCHAN_CFG_WT_M	0x000001c0
+#define    PAS_DMA_TXCHAN_CFG_LPDQ	0x00000800
+#define    PAS_DMA_TXCHAN_CFG_LPSQ	0x00000400
+#define    PAS_DMA_TXCHAN_CFG_WT_M	0x000003c0
 #define    PAS_DMA_TXCHAN_CFG_WT_S	6
 #define    PAS_DMA_TXCHAN_CFG_WT(x)	(((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
 					 PAS_DMA_TXCHAN_CFG_WT_M)
@@ -399,11 +404,62 @@ enum {
 				 XCT_COPY_LLEN_M)
 #define XCT_COPY_SE		0x0000000000000001ull
 
+/* Function descriptor fields */
+#define XCT_FUN_T		0x8000000000000000ull
+#define XCT_FUN_ST		0x4000000000000000ull
+#define XCT_FUN_RR_M		0x3000000000000000ull
+#define XCT_FUN_RR_NORES	0x0000000000000000ull
+#define XCT_FUN_RR_8BRES	0x1000000000000000ull
+#define XCT_FUN_RR_24BRES	0x2000000000000000ull
+#define XCT_FUN_RR_40BRES	0x3000000000000000ull
+#define XCT_FUN_I		0x0800000000000000ull
+#define XCT_FUN_O		0x0400000000000000ull
+#define XCT_FUN_E		0x0200000000000000ull
+#define XCT_FUN_FUN_M		0x01c0000000000000ull
+#define XCT_FUN_FUN_S		54
+#define XCT_FUN_FUN(x)		((((long)(x)) << XCT_FUN_FUN_S) & XCT_FUN_FUN_M)
+#define XCT_FUN_CRM_M		0x0038000000000000ull
+#define XCT_FUN_CRM_NOP		0x0000000000000000ull
+#define XCT_FUN_CRM_SIG		0x0008000000000000ull
+#define XCT_FUN_LLEN_M		0x0007ffff00000000ull
+#define XCT_FUN_LLEN_S		32
+#define XCT_FUN_LLEN(x)		((((long)(x)) << XCT_FUN_LLEN_S) & XCT_FUN_LLEN_M)
+#define XCT_FUN_SHL_M		0x00000000f8000000ull
+#define XCT_FUN_SHL_S		27
+#define XCT_FUN_SHL(x)		((((long)(x)) << XCT_FUN_SHL_S) & XCT_FUN_SHL_M)
+#define XCT_FUN_CHL_M		0x0000000007c00000ull
+#define XCT_FUN_HSZ_M		0x00000000003c0000ull
+#define XCT_FUN_ALG_M		0x0000000000038000ull
+#define XCT_FUN_HP		0x0000000000004000ull
+#define XCT_FUN_BCM_M		0x0000000000003800ull
+#define XCT_FUN_BCP_M		0x0000000000000600ull
+#define XCT_FUN_SIG_M		0x00000000000001f0ull
+#define XCT_FUN_SIG_TCP4	0x0000000000000140ull
+#define XCT_FUN_SIG_TCP6	0x0000000000000150ull
+#define XCT_FUN_SIG_UDP4	0x0000000000000160ull
+#define XCT_FUN_SIG_UDP6	0x0000000000000170ull
+#define XCT_FUN_A		0x0000000000000008ull
+#define XCT_FUN_C		0x0000000000000004ull
+#define XCT_FUN_AL2		0x0000000000000002ull
+#define XCT_FUN_SE		0x0000000000000001ull
+
+/* Function descriptor 8byte result fields */
+#define XCT_FUNRES_8B_CS_M	0x0000ffff00000000ull
+#define XCT_FUNRES_8B_CS_S	32
+#define XCT_FUNRES_8B_CRC_M	0x00000000ffffffffull
+#define XCT_FUNRES_8B_CRC_S	0
+
 /* Control descriptor fields */
 #define CTRL_CMD_T		0x8000000000000000ull
 #define CTRL_CMD_META_EVT	0x2000000000000000ull
 #define CTRL_CMD_O		0x0400000000000000ull
-#define CTRL_CMD_REG_M		0x000000000000000full
+#define CTRL_CMD_ETYPE_M	0x0038000000000000ull
+#define CTRL_CMD_ETYPE_EXT	0x0000000000000000ull
+#define CTRL_CMD_ETYPE_WSET	0x0020000000000000ull
+#define CTRL_CMD_ETYPE_WCLR	0x0028000000000000ull
+#define CTRL_CMD_ETYPE_SET	0x0030000000000000ull
+#define CTRL_CMD_ETYPE_CLR	0x0038000000000000ull
+#define CTRL_CMD_REG_M		0x000000000000007full
 #define CTRL_CMD_REG_S		0
 #define CTRL_CMD_REG(x)		((((long)(x)) << CTRL_CMD_REG_S) & \
 				 CTRL_CMD_REG_M)

-- 

^ permalink raw reply

* [patch 5/6] pasemi_mac: Enable GSO by default
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev
In-Reply-To: <20080221025753.903665000@lixom.net>

Ethtool support will handle the runtime toggling, but we do quite a bit
better with it on by default so just leave it on for now.


Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/drivers/net/pasemi_mac.c
===================================================================
--- k.org.orig/drivers/net/pasemi_mac.c
+++ k.org/drivers/net/pasemi_mac.c
@@ -1750,7 +1750,7 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 	netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
 
 	dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG |
-			NETIF_F_HIGHDMA;
+			NETIF_F_HIGHDMA | NETIF_F_GSO;
 
 	mac->lro_mgr.max_aggr = LRO_MAX_AGGR;
 	mac->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;

-- 

^ permalink raw reply

* [patch 6/6] pasemi_mac: basic ethtool support
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev
In-Reply-To: <20080221025753.903665000@lixom.net>

First cut at ethtool support, to be completed over time.


Signed-off-by: Olof Johansson <olof@lixom.net>

Index: 2.6.25/drivers/net/Makefile
===================================================================
--- 2.6.25.orig/drivers/net/Makefile
+++ 2.6.25/drivers/net/Makefile
@@ -218,7 +218,8 @@ obj-$(CONFIG_SMC911X) += smc911x.o
 obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
 obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
-obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
+obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
+pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
 obj-$(CONFIG_ENC28J60) += enc28j60.o
 
Index: 2.6.25/drivers/net/pasemi_mac.c
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.c
+++ 2.6.25/drivers/net/pasemi_mac.c
@@ -55,12 +55,6 @@
  * - Multiqueue RX/TX
  */
 
-
-/* Must be a power of two */
-#define RX_RING_SIZE 2048
-#define TX_RING_SIZE 4096
-#define CS_RING_SIZE (TX_RING_SIZE*2)
-
 #define LRO_MAX_AGGR 64
 
 #define PE_MIN_MTU	64
@@ -77,17 +71,6 @@
 	 NETIF_MSG_RX_ERR	| \
 	 NETIF_MSG_TX_ERR)
 
-#define TX_DESC(tx, num)	((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)])
-#define TX_DESC_INFO(tx, num)	((tx)->ring_info[(num) & (TX_RING_SIZE-1)])
-#define RX_DESC(rx, num)	((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
-#define RX_DESC_INFO(rx, num)	((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
-#define RX_BUFF(rx, num)	((rx)->buffers[(num) & (RX_RING_SIZE-1)])
-#define CS_DESC(cs, num)	((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)])
-
-#define RING_USED(ring)		(((ring)->next_to_fill - (ring)->next_to_clean) \
-				 & ((ring)->size - 1))
-#define RING_AVAIL(ring)	((ring->size) - RING_USED(ring))
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
 MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
@@ -96,6 +79,8 @@ static int debug = -1;	/* -1 == use DEFA
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
 
+extern const struct ethtool_ops pasemi_mac_ethtool_ops;
+
 static int translation_enabled(void)
 {
 #if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
@@ -1148,7 +1133,7 @@ static int pasemi_mac_open(struct net_de
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int flags;
-	int ret;
+	int i, ret;
 
 	flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
 		PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
@@ -1171,6 +1156,10 @@ static int pasemi_mac_open(struct net_de
 			goto out_tx_ring;
 	}
 
+	/* Zero out rmon counters */
+	for (i = 0; i < 32; i++)
+		write_mac_reg(mac, PAS_MAC_RMON(i), 0);
+
 	/* 0x3ff with 33MHz clock is about 31us */
 	write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
 		      PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));
@@ -1812,6 +1801,7 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 	mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
 
 	dev->change_mtu = pasemi_mac_change_mtu;
+	dev->ethtool_ops = &pasemi_mac_ethtool_ops;
 
 	if (err)
 		goto out;
Index: 2.6.25/drivers/net/pasemi_mac.h
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.h
+++ 2.6.25/drivers/net/pasemi_mac.h
@@ -26,6 +26,12 @@
 #include <linux/spinlock.h>
 #include <linux/phy.h>
 
+/* Must be a power of two */
+#define RX_RING_SIZE 2048
+#define TX_RING_SIZE 4096
+#define CS_RING_SIZE (TX_RING_SIZE*2)
+
+
 #define MAX_LRO_DESCRIPTORS 8
 #define MAX_CS	2
 
@@ -103,6 +109,16 @@ struct pasemi_mac_buffer {
 	dma_addr_t	dma;
 };
 
+#define TX_DESC(tx, num)	((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)])
+#define TX_DESC_INFO(tx, num)	((tx)->ring_info[(num) & (TX_RING_SIZE-1)])
+#define RX_DESC(rx, num)	((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
+#define RX_DESC_INFO(rx, num)	((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
+#define RX_BUFF(rx, num)	((rx)->buffers[(num) & (RX_RING_SIZE-1)])
+#define CS_DESC(cs, num)	((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)])
+
+#define RING_USED(ring)	(((ring)->next_to_fill - (ring)->next_to_clean) \
+				& ((ring)->size - 1))
+#define RING_AVAIL(ring)	((ring->size) - RING_USED(ring))
 
 /* PCI register offsets and formats */
 
@@ -114,6 +130,7 @@ enum {
 	PAS_MAC_CFG_ADR0 = 0x8c,
 	PAS_MAC_CFG_ADR1 = 0x90,
 	PAS_MAC_CFG_TXP = 0x98,
+	PAS_MAC_CFG_RMON = 0x100,
 	PAS_MAC_IPC_CHNL = 0x208,
 };
 
@@ -185,6 +202,8 @@ enum {
 #define PAS_MAC_CFG_TXP_TIFG(x)		(((x) << PAS_MAC_CFG_TXP_TIFG_S) & \
 					 PAS_MAC_CFG_TXP_TIFG_M)
 
+#define PAS_MAC_RMON(r)			(0x100+(r)*4)
+
 #define PAS_MAC_IPC_CHNL_DCHNO_M	0x003f0000
 #define PAS_MAC_IPC_CHNL_DCHNO_S	16
 #define PAS_MAC_IPC_CHNL_DCHNO(x)	(((x) << PAS_MAC_IPC_CHNL_DCHNO_S) & \
@@ -194,4 +213,5 @@ enum {
 #define PAS_MAC_IPC_CHNL_BCH(x)		(((x) << PAS_MAC_IPC_CHNL_BCH_S) & \
 					 PAS_MAC_IPC_CHNL_BCH_M)
 
+
 #endif /* PASEMI_MAC_H */
Index: 2.6.25/drivers/net/pasemi_mac_ethtool.c
===================================================================
--- /dev/null
+++ 2.6.25/drivers/net/pasemi_mac_ethtool.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2006-2008 PA Semi, Inc
+ *
+ * Ethtool hooks for the PA Semi PWRficient onchip 1G/10G Ethernet MACs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/inet_lro.h>
+
+#include <asm/pasemi_dma.h>
+#include "pasemi_mac.h"
+
+static struct {
+	const char str[ETH_GSTRING_LEN];
+} ethtool_stats_keys[] = {
+	{ "rx-drops" },
+	{ "rx-bytes" },
+	{ "rx-packets" },
+	{ "rx-broadcast-packets" },
+	{ "rx-multicast-packets" },
+	{ "rx-crc-errors" },
+	{ "rx-undersize-errors" },
+	{ "rx-oversize-errors" },
+	{ "rx-short-fragment-errors" },
+	{ "rx-jabber-errors" },
+	{ "rx-64-byte-packets" },
+	{ "rx-65-127-byte-packets" },
+	{ "rx-128-255-byte-packets" },
+	{ "rx-256-511-byte-packets" },
+	{ "rx-512-1023-byte-packets" },
+	{ "rx-1024-1518-byte-packets" },
+	{ "rx-pause-frames" },
+	{ "tx-bytes" },
+	{ "tx-packets" },
+	{ "tx-broadcast-packets" },
+	{ "tx-multicast-packets" },
+	{ "tx-collisions" },
+	{ "tx-late-collisions" },
+	{ "tx-excessive-collisions" },
+	{ "tx-crc-errors" },
+	{ "tx-undersize-errors" },
+	{ "tx-oversize-errors" },
+	{ "tx-64-byte-packets" },
+	{ "tx-65-127-byte-packets" },
+	{ "tx-128-255-byte-packets" },
+	{ "tx-256-511-byte-packets" },
+	{ "tx-512-1023-byte-packets" },
+	{ "tx-1024-1518-byte-packets" },
+};
+
+static int
+pasemi_mac_ethtool_get_settings(struct net_device *netdev,
+			       struct ethtool_cmd *cmd)
+{
+	struct pasemi_mac *mac = netdev_priv(netdev);
+	struct phy_device *phydev = mac->phydev;
+
+	return phy_ethtool_gset(phydev, cmd);
+}
+
+static void
+pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev,
+			       struct ethtool_drvinfo *drvinfo)
+{
+	struct pasemi_mac *mac;
+	mac = netdev_priv(netdev);
+
+	/* clear and fill out info */
+	memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
+	strncpy(drvinfo->driver, "pasemi_mac", 12);
+	strcpy(drvinfo->version, "N/A");
+	strcpy(drvinfo->fw_version, "N/A");
+	strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32);
+}
+
+static u32
+pasemi_mac_ethtool_get_msglevel(struct net_device *netdev)
+{
+	struct pasemi_mac *mac = netdev_priv(netdev);
+	return mac->msg_enable;
+}
+
+static void
+pasemi_mac_ethtool_set_msglevel(struct net_device *netdev,
+				u32 level)
+{
+	struct pasemi_mac *mac = netdev_priv(netdev);
+	mac->msg_enable = level;
+}
+
+
+static void
+pasemi_mac_ethtool_get_ringparam(struct net_device *netdev,
+				 struct ethtool_ringparam *ering)
+{
+	struct pasemi_mac *mac = netdev->priv;
+
+	ering->tx_max_pending = TX_RING_SIZE/2;
+	ering->tx_pending = RING_USED(mac->tx)/2;
+	ering->rx_max_pending = RX_RING_SIZE/4;
+	ering->rx_pending = RING_USED(mac->rx)/4;
+}
+
+static int pasemi_mac_get_sset_count(struct net_device *netdev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(ethtool_stats_keys);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void pasemi_mac_get_ethtool_stats(struct net_device *netdev,
+		struct ethtool_stats *stats, u64 *data)
+{
+	struct pasemi_mac *mac = netdev->priv;
+	int i;
+
+	data[0] = pasemi_read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if))
+			>> PAS_DMA_RXINT_RCMDSTA_DROPS_S;
+	for (i = 0; i < 32; i++)
+		data[1+i] = pasemi_read_mac_reg(mac->dma_if, PAS_MAC_RMON(i));
+}
+
+static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset,
+				   u8 *data)
+{
+	memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
+}
+
+const struct ethtool_ops pasemi_mac_ethtool_ops = {
+	.get_settings		= pasemi_mac_ethtool_get_settings,
+	.get_drvinfo		= pasemi_mac_ethtool_get_drvinfo,
+	.get_msglevel		= pasemi_mac_ethtool_get_msglevel,
+	.set_msglevel		= pasemi_mac_ethtool_set_msglevel,
+	.get_link		= ethtool_op_get_link,
+	.get_ringparam          = pasemi_mac_ethtool_get_ringparam,
+	.get_strings		= pasemi_mac_get_strings,
+	.get_sset_count		= pasemi_mac_get_sset_count,
+	.get_ethtool_stats	= pasemi_mac_get_ethtool_stats,
+};
+

-- 

^ permalink raw reply

* Re: [patch v8 3/4] USB: add Cypress c67x00 OTG controller HCD driver
From: David Brownell @ 2008-02-21  3:06 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: dbrownell, greg, linux-usb, linuxppc-dev, stern
In-Reply-To: <20080220091401.612406000@sunsite.dk>

On Wednesday 20 February 2008, Peter Korsgaard wrote:
> +ifeq ($(CONFIG_USB_DEBUG),y)
> +       EXTRA_CFLAGS            += -DDEBUG
> +endif

The canonical Sam Ravnborg comment is to replace that with:

  +ccflags-$(CONFIG_USB_DEBUG)    += -DDEBUG

It's a newish idiom, most easily applied to new code before
it merges ...  :)


> +++ linux-2.6/drivers/usb/host/Kconfig
> @@ -261,3 +261,15 @@
>           To compile this driver as a module, choose M here: the
>           module will be called r8a66597-hcd.
>  
> +config USB_C67X00_HCD
> +       tristate "Cypress C67x00 HCD support"
> +       depends on USB

And I realize that some of the drivers there have violated the
normal "alphabetical order" convention, so maybe one big
cleanup patch would be in order ... but still, I'd rather see
such new options added in the right place, rather than need
to see them fixed up later.

- Dave

^ permalink raw reply

* Re: [PATCH v2][POWERPC] Fix initial lmb add region with a non-zero base
From: Josh Boyer @ 2008-02-21  4:01 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: sparclinux, linuxppc-dev, linux-kernel, David Miller
In-Reply-To: <18364.57054.427433.405627@cargo.ozlabs.ibm.com>

On Thu, 21 Feb 2008 13:15:58 +1100
Paul Mackerras <paulus@samba.org> wrote:

> Kumar Gala writes:
> 
> > np.  Are we trying to get this into 2.6.25 or .26?
> 
> I was going to put it into my powerpc-next branch and put it in
> 2.6.26.  I don't see any need for it to go in 2.6.25.

Is that a new branch you're going to create, or the normal "for-2.6.xx"?

josh

^ permalink raw reply

* Re: Question about PPC_NATIVE/hash_native_64.c
From: Paul Mackerras @ 2008-02-21  4:47 UTC (permalink / raw)
  To: Gerhard Pircher; +Cc: linuxppc-dev
In-Reply-To: <20080220115713.193460@gmx.net>

Gerhard Pircher writes:

> I'm a little bit confused about the hash_native_64.c file, which is compiled
> in the kernel, if PPC_NATIVE is defined. PPC_NATIVE seems to be defined also
> for 32bit platforms (CHRP, PREP, etc.), but the name of the hash_native_64.c
> file and the Makefile suggest that it is for 64bit platforms only.
> What is hash_native_64.c actually good for on 32bit platforms and which cpus
> can make use of it?

It's not included on 32-bit platforms.  Here are the relevant lines
from arch/powerpc/mm/Makefile:

hash-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
obj-$(CONFIG_PPC64)		+= hash_utils_64.o \
				   slb_low.o slb.o stab.o mmap.o $(hash-y)

Note that the first line sets hash-y not obj-y, and $(hash-y) is only
used on 64-bit machines.

Paul.

^ permalink raw reply

* Re: [Linux-fbdev-devel] [PATCH 1/2] fb: add support for foreign endianness
From: Paul Mackerras @ 2008-02-21  4:59 UTC (permalink / raw)
  To: avorontsov
  Cc: linux-fbdev-devel, adaplas, Krzysztof Helt, linux-kernel,
	linuxppc-dev, Geert Uytterhoeven, Andrew Morton
In-Reply-To: <20080220121818.GA20836@localhost.localdomain>

Anton Vorontsov writes:

> > I was wondering if it would be sufficient to provide alternative
> > versions of fb_readl, fb_writel etc. that do byte-swapping.
> 
> This is of course viable alternative. And I was considering this, but
> later I abandoned the idea: that way we'll end up doing math in the
> native endianness and then converting it to the foreign. This feels
> ugly in contrast when we can do the right math in the first place, per
> framebuffer.

OK.  I guess I'm convinced then.  However, your patch description
needs to be a lot better.  It should describe things like why you
want to make the change and why the change you are proposing is a good
idea and is better than other alternatives.  If you'd done that
originally we might not have needed to have all this discussion. :)

Paul.

^ permalink raw reply

* EBC access
From: Silwer star @ 2008-02-21  5:48 UTC (permalink / raw)
  To: linuxppc-embedded


Hi,

I am working on the PPC 405EX processor with a peripheral attached to the
EBC. I've requested for I/O memory & mapped it using ioremap. The following
are my doubts:

1) How do I ensure that the memory range that I requested is non-cacheable.
I've to work with non-cacheable memory.  I've requested for memory using
request_mem_region( ). 
2) Between any consecutive writes or any consecutive reads, if I introduce a
delay of 500msec, the read/write is completing.  Does this have to do
anything with caching? What could be the  reason for this?

Any help will be appreciated.

Regards,
Silwer Star
-- 
View this message in context: http://www.nabble.com/EBC-access-tp15605219p15605219.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* Re: [PATCH] mpic: make sparse happy
From: Milton Miller @ 2008-02-21  5:50 UTC (permalink / raw)
  To: Johannes Berg; +Cc: ppcdev
In-Reply-To: <1203507104.17534.32.camel@johannes.berg>

At Wed Feb 20 22:31:44 EST 2008, Johannes Berg wrote:
> I was running sparse on something else and noticed sparse warnings
> and especially the bogus code that is fixed by the first hunk of
> this patch, so I fixed them all while at it.

But your change is not equivalent!

> --- everything.orig/arch/powerpc/sysdev/mpic.c  2008-02-20 
> 12:25:41.000000000 +0100
> +++ everything/arch/powerpc/sysdev/mpic.c       2008-02-20 
> 12:28:37.000000000 +0100
> @@ -175,13 +175,13 @@ static inline void _mpic_write(enum mpic
>         switch(type) {
>  #ifdef CONFIG_PPC_DCR
>         case mpic_access_dcr:
> -               return dcr_write(rb->dhost, reg, value);
> +               dcr_write(rb->dhost, reg, value);
>  #endif
>         case mpic_access_mmio_be:
> -               return out_be32(rb->base + (reg >> 2), value);
> +               out_be32(rb->base + (reg >> 2), value);
>         case mpic_access_mmio_le:
>         default:
> -               return out_le32(rb->base + (reg >> 2), value);
> +               out_le32(rb->base + (reg >> 2), value);
>         }
>  }

You now write to the register with dcr, big, and little endian variants!

Either put a return or break after the calls to the void functions so 
you don't fall through.

...

> @@ -1107,10 +1108,10 @@ struct mpic * __init mpic_alloc(struct d
>          * in, try to obtain one
>          */
>         if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) {
> -               const u32 *reg;
> -               reg = of_get_property(node, "reg", NULL);
> -               BUG_ON(reg == NULL);
> -               paddr = of_translate_address(node, reg);
> +               const u32 *regprop;
> +               regprop = of_get_property(node, "reg", NULL);
> +               BUG_ON(regprop == NULL);
> +               paddr = of_translate_address(node, regprop);
>                 BUG_ON(paddr == OF_BAD_ADDR);
>         }

This is reg variable is shadowed ... ok, although i might have renamed 
the outer one features or greg_feature.  For that matter, I would have 
initialized this reg/regprop on definition.

^ permalink raw reply

* Re: [PATCH] powerpc: don't create two devices for each cpm_uart device tree node
From: Nikita V. Youshchenko @ 2008-02-21  6:13 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080220164052.GB32165@ld0162-tx32.am.freescale.net>

> On Wed, Feb 20, 2008 at 02:32:33AM +0300, Nikita V. Youshchenko wrote:
> >     powerpc: don't create two devices for each cpm_uart device tree
> > node
> >
> >     Code in arch/powerpc/sysdev/fsl_soc.c used to create two 'struct
> > device' objects for each cpm_uart device tree node - one
> > "fsl-cpm-scc:uart" in cpm_uart_of_init() and one "fsl-cpm-smc:uart" in
> > cpm_smc_uart_of_init().
>
> This is old code that only exists for non-CONFIG_PPC_CPM_NEW_BINDING
> boards.  As there are none of these remaining in-tree, this code should
> go away soon.

Thank you for information.

I am working with vendor kernel, based on 2.6.18, and that does not have 
CONFIG_PPC_CPM_NEW_BINDING. I thought that fix I made for that kernel 
could be usable for mainline, but if not - nevermind.

^ permalink raw reply

* Re: Sample driver
From: Jeff Mock @ 2008-02-21  6:54 UTC (permalink / raw)
  To: fariyaf; +Cc: linuxppc-embedded
In-Reply-To: <8024567.229231203576334424.JavaMail.nabble@isper.nabble.com>



fariyaf@gmail.com wrote:
> Hi,
> 
> Thanks so much for the driver. I have a few doubts.. .may be u cud
> help me out with it.... Basically, I am working on the PPC 405EX
> processor with a peripheral attached to the EBC. I've requested for
> I/O memory & mapped it using ioremap. The following are my doubts:
> 
> 1) How do I ensure that the memory range that I requested is
> non-cacheable. I've to work with non-cacheable memory.  I've
> requested for memory using request_mem_region( ).

In my example the memory range is set to non-cacheable, this needs to be 
done if you are talking to real hardware registers:

   "vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);"

static int
pdev_mmap(struct file *file, struct vm_area_struct *vma)
{
     int fpga_num = iminor(file->f_dentry->d_inode) - PDEV_SPCTL;
     phys_addr_t     paddr;

     paddr = fpga_num ? PDEV_SP1_REG : PDEV_SP0_REG;
#ifdef PDEV_DEBUG
     printk("pdev-gxctl: fpga %d reg mmap() at %016llx\n", fpga_num, paddr);
#endif
     vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
     if (remap_pfn_range(vma,
             vma->vm_start,
             paddr >> PAGE_SHIFT,
             vma->vm_end-vma->vm_start,
             vma->vm_page_prot))
         return -EAGAIN;
     return 0;
}

> 2) Between any consecutive writes or any consecutive reads to the EBC
> peripheral, if I introduce a delay of 500msec, the read/write is
> completing.  Does this have to do anything with caching? What could
> be the  reason for this?


I have no idea where the 500ms delay comes from, this is quite a long 
delay.  Maybe there is some problem with the EBC programming for your 
example.  The EBC is quite flexible and can be programmed in any number 
of insane ways that might cause trouble.

jeff

^ permalink raw reply

* Xilinx  PowerPC
From: David H. Lynch Jr. @ 2008-02-21  6:58 UTC (permalink / raw)
  To: Grant Likely, linuxppc-embedded

    So when you have Xilinx under powerpc working, do we pull it from your
    git tree or the xilinx one ?

    Will there be an announcement ?

    How about a one paragraph getting started guide to moving a xilinx
ppc bsp to
    xilinx powerpc.

    Like  ?

    step 1).
             Generate a dts - gen-mhs-devicetree ?
             And pass it to through your boot loader to Linux ?
   
    Step 2).
             the code in arch/powerpc/???? is the devicetree equvalent to
             arch/ppc/platforms/4xx/xilinx_ml410.c

    Step 3).
             device drivers need to change initialization/setup from
             ???? to ???
      
    Just something to give those of us with no clue, a small one to start.

     Thanks.

^ permalink raw reply

* Block devices
From: David H. Lynch Jr. @ 2008-02-21  7:05 UTC (permalink / raw)
  To: linuxppc-embedded, linux-fsdevel, linux-mtd

    Sometime recently it seems to have become possible to disable the
whole block device subsystem.
    Though in my tests I can't quit build with it disabled.

     Anyway, for an embedded device this might be appealing.
    how does this interact with initramfs and flash ?
   
    Can I boot an initramfs kernel without a block device ?
    Can I write a filesystem driver for a flash device that does not
require a block device ?
    Are their any examples of something even close ?

   

      







-- 
Dave Lynch 					  	    DLA Systems
Software Development:  				         Embedded Linux
717.627.3770 	       dhlii@dlasys.net 	  http://www.dlasys.net
fax: 1.253.369.9244 			           Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.

"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein

^ permalink raw reply

* Re: [patch v8 3/4] USB: add Cypress c67x00 OTG controller HCD driver
From: Peter Korsgaard @ 2008-02-21  7:53 UTC (permalink / raw)
  To: David Brownell; +Cc: dbrownell, greg, linux-usb, linuxppc-dev, stern
In-Reply-To: <200802201906.35830.david-b@pacbell.net>

>>>>> "David" == David Brownell <david-b@pacbell.net> writes:

Hi,

 David>   +ccflags-$(CONFIG_USB_DEBUG)    += -DDEBUG

 David> It's a newish idiom, most easily applied to new code before
 David> it merges ...  :)

Ok. I'll fix that.

 David> And I realize that some of the drivers there have violated the
 David> normal "alphabetical order" convention, so maybe one big
 David> cleanup patch would be in order ... but still, I'd rather see
 David> such new options added in the right place, rather than need
 David> to see them fixed up later.

And this as well.

-- 
Bye, Peter Korsgaard

^ permalink raw reply

* Re: MPC8641D PCI-Express error
From: Marco Stornelli @ 2008-02-21  8:02 UTC (permalink / raw)
  To: Kumar Gala; +Cc: LinuxPPC-Embedded
In-Reply-To: <BA5ADBDE-BDE5-4126-B012-DA6C5A8F8EF3@kernel.crashing.org>

Kumar Gala ha scritto:
> 
> On Feb 20, 2008, at 10:13 AM, Marco Stornelli wrote:
> 
>> Kumar Gala wrote:
>>>> Marco Stornelli wrote:
>>>>
>>>>> No, but I can try to backport the PCI-E code from 2.6.24 to 2.6.18
>>>>> if it could help. What do you think about it? Do you think this
>>>>> problem could be not present in 2.6.24?
>>>>> I have no idea there, honestly.  Sorry.
>>
>>> As Jon said, try 2.6.24 and see if it has an issue, if so we can look
>>> at helping.  if not, you know you need to back port the fixes.
>>
>>> - k
>>
>> I've "backported" the PCI-Express code from 2.6.24 to 2.6.18, but it
>> still doesn't work, I have the same problem (sigh), could you give me
>> any suggestions?
> 
> did 2.6.24 work for you or not?
> 
> - k
> 
No, it didn't. I have the same problem even with the 2.6.18 plus the
2.6.24 PCI-Express code. I performed this action because I can't change
kernel version but I can modify it.

Marco

^ permalink raw reply

* Re: [PATCH] mpic: make sparse happy
From: Johannes Berg @ 2008-02-21  9:23 UTC (permalink / raw)
  To: Milton Miller; +Cc: ppcdev
In-Reply-To: <91eb052edd9d5c608658fcdcfdc7589c@bga.com>

[-- Attachment #1: Type: text/plain, Size: 468 bytes --]


On Wed, 2008-02-20 at 23:50 -0600, Milton Miller wrote:
> At Wed Feb 20 22:31:44 EST 2008, Johannes Berg wrote:
> > I was running sparse on something else and noticed sparse warnings
> > and especially the bogus code that is fixed by the first hunk of
> > this patch, so I fixed them all while at it.
> 
> But your change is not equivalent!

> You now write to the register with dcr, big, and little endian variants!

Ouch, you're right, doh.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ 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