aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-03-22 21:22:42 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-22 21:22:42 -0400
commit76fef2b6bffa13ad7ccd54c0493b053295721b9a (patch)
treef4509477d413398b7155fb3c35453ab26bd81bce /drivers
parent817bc4db7794d6dc6594265ddea88d2b839cf2f8 (diff)
parentef8500457b29eed13d03ff19af36d810308e57b7 (diff)
Merge branch 'upstream-net26' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Conflicts: drivers/s390/net/qeth_main.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/8390.c6
-rw-r--r--drivers/net/Kconfig87
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/appletalk/cops.c6
-rw-r--r--drivers/net/arcnet/com20020.c7
-rw-r--r--drivers/net/at1700.c7
-rw-r--r--drivers/net/atarilance.c7
-rw-r--r--drivers/net/atl1/Makefile2
-rw-r--r--drivers/net/atl1/atl1.h286
-rw-r--r--drivers/net/atl1/atl1_ethtool.c505
-rw-r--r--drivers/net/atl1/atl1_hw.c720
-rw-r--r--drivers/net/atl1/atl1_hw.h946
-rw-r--r--drivers/net/atl1/atl1_param.c203
-rw-r--r--drivers/net/atlx/Makefile1
-rw-r--r--drivers/net/atlx/atl1.c (renamed from drivers/net/atl1/atl1_main.c)2120
-rw-r--r--drivers/net/atlx/atl1.h796
-rw-r--r--drivers/net/atlx/atlx.c433
-rw-r--r--drivers/net/atlx/atlx.h506
-rw-r--r--drivers/net/ixgbe/ixgbe.h87
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c39
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1520
-rw-r--r--drivers/net/s2io.c444
-rw-r--r--drivers/net/s2io.h50
-rw-r--r--drivers/net/sk98lin/Makefile87
-rw-r--r--drivers/net/sk98lin/h/lm80.h179
-rw-r--r--drivers/net/sk98lin/h/skaddr.h285
-rw-r--r--drivers/net/sk98lin/h/skcsum.h213
-rw-r--r--drivers/net/sk98lin/h/skdebug.h74
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h188
-rw-r--r--drivers/net/sk98lin/h/skdrv2nd.h447
-rw-r--r--drivers/net/sk98lin/h/skerror.h55
-rw-r--r--drivers/net/sk98lin/h/skgedrv.h51
-rw-r--r--drivers/net/sk98lin/h/skgehw.h2126
-rw-r--r--drivers/net/sk98lin/h/skgehwt.h48
-rw-r--r--drivers/net/sk98lin/h/skgei2c.h210
-rw-r--r--drivers/net/sk98lin/h/skgeinit.h797
-rw-r--r--drivers/net/sk98lin/h/skgepnm2.h334
-rw-r--r--drivers/net/sk98lin/h/skgepnmi.h962
-rw-r--r--drivers/net/sk98lin/h/skgesirq.h110
-rw-r--r--drivers/net/sk98lin/h/ski2c.h174
-rw-r--r--drivers/net/sk98lin/h/skqueue.h94
-rw-r--r--drivers/net/sk98lin/h/skrlmt.h438
-rw-r--r--drivers/net/sk98lin/h/sktimer.h63
-rw-r--r--drivers/net/sk98lin/h/sktypes.h69
-rw-r--r--drivers/net/sk98lin/h/skversion.h38
-rw-r--r--drivers/net/sk98lin/h/skvpd.h248
-rw-r--r--drivers/net/sk98lin/h/xmac_ii.h1579
-rw-r--r--drivers/net/sk98lin/skaddr.c1788
-rw-r--r--drivers/net/sk98lin/skdim.c742
-rw-r--r--drivers/net/sk98lin/skethtool.c627
-rw-r--r--drivers/net/sk98lin/skge.c5218
-rw-r--r--drivers/net/sk98lin/skgehwt.c171
-rw-r--r--drivers/net/sk98lin/skgeinit.c2005
-rw-r--r--drivers/net/sk98lin/skgemib.c1075
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8198
-rw-r--r--drivers/net/sk98lin/skgesirq.c2229
-rw-r--r--drivers/net/sk98lin/ski2c.c1296
-rw-r--r--drivers/net/sk98lin/sklm80.c141
-rw-r--r--drivers/net/sk98lin/skqueue.c179
-rw-r--r--drivers/net/sk98lin/skrlmt.c3257
-rw-r--r--drivers/net/sk98lin/sktimer.c250
-rw-r--r--drivers/net/sk98lin/skvpd.c1091
-rw-r--r--drivers/net/sk98lin/skxmac2.c4160
-rw-r--r--drivers/net/smc91x.c335
-rw-r--r--drivers/net/smc91x.h331
-rw-r--r--drivers/net/tulip/Kconfig15
-rw-r--r--drivers/net/tulip/Makefile1
-rw-r--r--drivers/net/tulip/xircom_tulip_cb.c1726
-rw-r--r--drivers/s390/net/Kconfig84
-rw-r--r--drivers/s390/net/Makefile12
-rw-r--r--drivers/s390/net/ctcdbug.c80
-rw-r--r--drivers/s390/net/ctcdbug.h125
-rw-r--r--drivers/s390/net/ctcm_dbug.c67
-rw-r--r--drivers/s390/net/ctcm_dbug.h158
-rw-r--r--drivers/s390/net/ctcm_fsms.c2347
-rw-r--r--drivers/s390/net/ctcm_fsms.h359
-rw-r--r--drivers/s390/net/ctcm_main.c1772
-rw-r--r--drivers/s390/net/ctcm_main.h287
-rw-r--r--drivers/s390/net/ctcm_mpc.c2472
-rw-r--r--drivers/s390/net/ctcm_mpc.h239
-rw-r--r--drivers/s390/net/ctcm_sysfs.c210
-rw-r--r--drivers/s390/net/ctcmain.c3062
-rw-r--r--drivers/s390/net/ctcmain.h270
-rw-r--r--drivers/s390/net/qeth_core.h (renamed from drivers/s390/net/qeth.h)811
-rw-r--r--drivers/s390/net/qeth_core_main.c4540
-rw-r--r--drivers/s390/net/qeth_core_mpc.c266
-rw-r--r--drivers/s390/net/qeth_core_mpc.h (renamed from drivers/s390/net/qeth_mpc.h)143
-rw-r--r--drivers/s390/net/qeth_core_offl.c (renamed from drivers/s390/net/qeth_eddp.c)287
-rw-r--r--drivers/s390/net/qeth_core_offl.h (renamed from drivers/s390/net/qeth_eddp.h)50
-rw-r--r--drivers/s390/net/qeth_core_sys.c651
-rw-r--r--drivers/s390/net/qeth_fs.h168
-rw-r--r--drivers/s390/net/qeth_l2_main.c1242
-rw-r--r--drivers/s390/net/qeth_l3.h76
-rw-r--r--drivers/s390/net/qeth_l3_main.c3391
-rw-r--r--drivers/s390/net/qeth_l3_sys.c1051
-rw-r--r--drivers/s390/net/qeth_main.c8959
-rw-r--r--drivers/s390/net/qeth_mpc.c269
-rw-r--r--drivers/s390/net/qeth_proc.c316
-rw-r--r--drivers/s390/net/qeth_sys.c1858
-rw-r--r--drivers/s390/net/qeth_tso.h148
100 files changed, 25074 insertions, 63181 deletions
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index a82807641dcf..0ed41a3d9dcb 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -48,14 +48,16 @@ EXPORT_SYMBOL(__alloc_ei_netdev);
48 48
49#if defined(MODULE) 49#if defined(MODULE)
50 50
51int init_module(void) 51static int __init ns8390_module_init(void)
52{ 52{
53 return 0; 53 return 0;
54} 54}
55 55
56void cleanup_module(void) 56static void __exit ns8390_module_exit(void)
57{ 57{
58} 58}
59 59
60module_init(ns8390_init_module);
61module_exit(ns8390_module_exit);
60#endif /* MODULE */ 62#endif /* MODULE */
61MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index fe7b5ec09708..978e72ab39c2 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2220,93 +2220,6 @@ config SKY2_DEBUG
2220 2220
2221 If unsure, say N. 2221 If unsure, say N.
2222 2222
2223config SK98LIN
2224 tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
2225 depends on PCI
2226 ---help---
2227 Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
2228 compliant Gigabit Ethernet Adapter.
2229
2230 This driver supports the original Yukon chipset. This driver is
2231 deprecated and will be removed from the kernel in the near future,
2232 it has been replaced by the skge driver. skge is cleaner and
2233 seems to work better.
2234
2235 This driver does not support the newer Yukon2 chipset. A separate
2236 driver, sky2, is provided to support Yukon2-based adapters.
2237
2238 The following adapters are supported by this driver:
2239 - 3Com 3C940 Gigabit LOM Ethernet Adapter
2240 - 3Com 3C941 Gigabit LOM Ethernet Adapter
2241 - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
2242 - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
2243 - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
2244 - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
2245 - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
2246 - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
2247 - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
2248 - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
2249 - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
2250 - EG1032 v2 Instant Gigabit Network Adapter
2251 - EG1064 v2 Instant Gigabit Network Adapter
2252 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
2253 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
2254 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
2255 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
2256 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
2257 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
2258 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
2259 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
2260 - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
2261 - Marvell RDK-8001 Adapter
2262 - Marvell RDK-8002 Adapter
2263 - Marvell RDK-8003 Adapter
2264 - Marvell RDK-8004 Adapter
2265 - Marvell RDK-8006 Adapter
2266 - Marvell RDK-8007 Adapter
2267 - Marvell RDK-8008 Adapter
2268 - Marvell RDK-8009 Adapter
2269 - Marvell RDK-8010 Adapter
2270 - Marvell RDK-8011 Adapter
2271 - Marvell RDK-8012 Adapter
2272 - Marvell RDK-8052 Adapter
2273 - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
2274 - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
2275 - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
2276 - SK-9521 10/100/1000Base-T Adapter
2277 - SK-9521 V2.0 10/100/1000Base-T Adapter
2278 - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
2279 - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
2280 - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
2281 - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
2282 - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
2283 - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
2284 - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
2285 - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
2286 - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
2287 - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
2288 - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
2289 - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
2290 - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
2291 - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
2292 - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
2293 - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
2294 - SMC EZ Card 1000 (SMC9452TXV.2)
2295
2296 The adapters support Jumbo Frames.
2297 The dual link adapters support link-failover and dual port features.
2298 Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support
2299 the scatter-gather functionality with sendfile(). Please refer to
2300 <file:Documentation/networking/sk98lin.txt> for more information about
2301 optional driver parameters.
2302 Questions concerning this driver may be addressed to:
2303 <linux@syskonnect.de>
2304
2305 If you want to compile this driver as a module ( = code which can be
2306 inserted in and removed from the running kernel whenever you want),
2307 say M here and read <file:Documentation/kbuild/modules.txt>. The module will
2308 be called sk98lin. This is recommended.
2309
2310config VIA_VELOCITY 2223config VIA_VELOCITY
2311 tristate "VIA Velocity support" 2224 tristate "VIA Velocity support"
2312 depends on PCI 2225 depends on PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3b1ea321dc05..960999c97c69 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_CHELSIO_T3) += cxgb3/
15obj-$(CONFIG_EHEA) += ehea/ 15obj-$(CONFIG_EHEA) += ehea/
16obj-$(CONFIG_CAN) += can/ 16obj-$(CONFIG_CAN) += can/
17obj-$(CONFIG_BONDING) += bonding/ 17obj-$(CONFIG_BONDING) += bonding/
18obj-$(CONFIG_ATL1) += atl1/ 18obj-$(CONFIG_ATL1) += atlx/
19obj-$(CONFIG_GIANFAR) += gianfar_driver.o 19obj-$(CONFIG_GIANFAR) += gianfar_driver.o
20obj-$(CONFIG_TEHUTI) += tehuti.o 20obj-$(CONFIG_TEHUTI) += tehuti.o
21 21
@@ -75,7 +75,6 @@ ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y)
75obj-$(CONFIG_TC35815) += tc35815.o 75obj-$(CONFIG_TC35815) += tc35815.o
76obj-$(CONFIG_SKGE) += skge.o 76obj-$(CONFIG_SKGE) += skge.o
77obj-$(CONFIG_SKY2) += sky2.o 77obj-$(CONFIG_SKY2) += sky2.o
78obj-$(CONFIG_SK98LIN) += sk98lin/
79obj-$(CONFIG_SKFP) += skfp/ 78obj-$(CONFIG_SKFP) += skfp/
80obj-$(CONFIG_VIA_RHINE) += via-rhine.o 79obj-$(CONFIG_VIA_RHINE) += via-rhine.o
81obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o 80obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 92c3a4cf0bb1..65b901ebfd62 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -1010,7 +1010,7 @@ module_param(io, int, 0);
1010module_param(irq, int, 0); 1010module_param(irq, int, 0);
1011module_param(board_type, int, 0); 1011module_param(board_type, int, 0);
1012 1012
1013int __init init_module(void) 1013static int __init cops_module_init(void)
1014{ 1014{
1015 if (io == 0) 1015 if (io == 0)
1016 printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", 1016 printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
@@ -1021,12 +1021,14 @@ int __init init_module(void)
1021 return 0; 1021 return 0;
1022} 1022}
1023 1023
1024void __exit cleanup_module(void) 1024static void __exit cops_module_exit(void)
1025{ 1025{
1026 unregister_netdev(cops_dev); 1026 unregister_netdev(cops_dev);
1027 cleanup_card(cops_dev); 1027 cleanup_card(cops_dev);
1028 free_netdev(cops_dev); 1028 free_netdev(cops_dev);
1029} 1029}
1030module_init(cops_module_init);
1031module_exit(cops_module_exit);
1030#endif /* MODULE */ 1032#endif /* MODULE */
1031 1033
1032/* 1034/*
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 7cf0a2511697..8b51313b1300 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -348,14 +348,15 @@ MODULE_LICENSE("GPL");
348 348
349#ifdef MODULE 349#ifdef MODULE
350 350
351int init_module(void) 351static int __init com20020_module_init(void)
352{ 352{
353 BUGLVL(D_NORMAL) printk(VERSION); 353 BUGLVL(D_NORMAL) printk(VERSION);
354 return 0; 354 return 0;
355} 355}
356 356
357void cleanup_module(void) 357static void __exit com20020_module_exit(void)
358{ 358{
359} 359}
360 360module_init(com20020_module_init);
361module_exit(com20020_module_exit);
361#endif /* MODULE */ 362#endif /* MODULE */
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 24d81f922533..7e874d485d24 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -881,7 +881,7 @@ MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address");
881MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number"); 881MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number");
882MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)"); 882MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)");
883 883
884int __init init_module(void) 884static int __init at1700_module_init(void)
885{ 885{
886 if (io == 0) 886 if (io == 0)
887 printk("at1700: You should not use auto-probing with insmod!\n"); 887 printk("at1700: You should not use auto-probing with insmod!\n");
@@ -891,13 +891,14 @@ int __init init_module(void)
891 return 0; 891 return 0;
892} 892}
893 893
894void __exit 894static void __exit at1700_module_exit(void)
895cleanup_module(void)
896{ 895{
897 unregister_netdev(dev_at1700); 896 unregister_netdev(dev_at1700);
898 cleanup_card(dev_at1700); 897 cleanup_card(dev_at1700);
899 free_netdev(dev_at1700); 898 free_netdev(dev_at1700);
900} 899}
900module_init(at1700_module_init);
901module_exit(at1700_module_exit);
901#endif /* MODULE */ 902#endif /* MODULE */
902MODULE_LICENSE("GPL"); 903MODULE_LICENSE("GPL");
903 904
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 13c293b286de..4cceaac8863a 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -1155,7 +1155,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
1155#ifdef MODULE 1155#ifdef MODULE
1156static struct net_device *atarilance_dev; 1156static struct net_device *atarilance_dev;
1157 1157
1158int __init init_module(void) 1158static int __init atarilance_module_init(void)
1159{ 1159{
1160 atarilance_dev = atarilance_probe(-1); 1160 atarilance_dev = atarilance_probe(-1);
1161 if (IS_ERR(atarilance_dev)) 1161 if (IS_ERR(atarilance_dev))
@@ -1163,13 +1163,14 @@ int __init init_module(void)
1163 return 0; 1163 return 0;
1164} 1164}
1165 1165
1166void __exit cleanup_module(void) 1166static void __exit atarilance_module_exit(void)
1167{ 1167{
1168 unregister_netdev(atarilance_dev); 1168 unregister_netdev(atarilance_dev);
1169 free_irq(atarilance_dev->irq, atarilance_dev); 1169 free_irq(atarilance_dev->irq, atarilance_dev);
1170 free_netdev(atarilance_dev); 1170 free_netdev(atarilance_dev);
1171} 1171}
1172 1172module_init(atarilance_module_init);
1173module_exit(atarilance_module_exit);
1173#endif /* MODULE */ 1174#endif /* MODULE */
1174 1175
1175 1176
diff --git a/drivers/net/atl1/Makefile b/drivers/net/atl1/Makefile
deleted file mode 100644
index a6b707e4e69e..000000000000
--- a/drivers/net/atl1/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_ATL1) += atl1.o
2atl1-y += atl1_main.o atl1_hw.o atl1_ethtool.o atl1_param.o
diff --git a/drivers/net/atl1/atl1.h b/drivers/net/atl1/atl1.h
deleted file mode 100644
index ff4765f6c3de..000000000000
--- a/drivers/net/atl1/atl1.h
+++ /dev/null
@@ -1,286 +0,0 @@
1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
5 *
6 * Derived from Intel e1000 driver
7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#ifndef _ATL1_H_
25#define _ATL1_H_
26
27#include <linux/types.h>
28#include <linux/if_vlan.h>
29
30#include "atl1_hw.h"
31
32/* function prototypes needed by multiple files */
33s32 atl1_up(struct atl1_adapter *adapter);
34void atl1_down(struct atl1_adapter *adapter);
35int atl1_reset(struct atl1_adapter *adapter);
36s32 atl1_setup_ring_resources(struct atl1_adapter *adapter);
37void atl1_free_ring_resources(struct atl1_adapter *adapter);
38
39extern char atl1_driver_name[];
40extern char atl1_driver_version[];
41extern const struct ethtool_ops atl1_ethtool_ops;
42
43struct atl1_adapter;
44
45#define ATL1_MAX_INTR 3
46#define ATL1_MAX_TX_BUF_LEN 0x3000 /* 12288 bytes */
47
48#define ATL1_DEFAULT_TPD 256
49#define ATL1_MAX_TPD 1024
50#define ATL1_MIN_TPD 64
51#define ATL1_DEFAULT_RFD 512
52#define ATL1_MIN_RFD 128
53#define ATL1_MAX_RFD 2048
54
55#define ATL1_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
56#define ATL1_RFD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_free_desc)
57#define ATL1_TPD_DESC(R, i) ATL1_GET_DESC(R, i, struct tx_packet_desc)
58#define ATL1_RRD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_return_desc)
59
60/*
61 * This detached comment is preserved for documentation purposes only.
62 * It was originally attached to some code that got deleted, but seems
63 * important enough to keep around...
64 *
65 * <begin detached comment>
66 * Some workarounds require millisecond delays and are run during interrupt
67 * context. Most notably, when establishing link, the phy may need tweaking
68 * but cannot process phy register reads/writes faster than millisecond
69 * intervals...and we establish link due to a "link status change" interrupt.
70 * <end detached comment>
71 */
72
73/*
74 * atl1_ring_header represents a single, contiguous block of DMA space
75 * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
76 * message blocks (cmb, smb) described below
77 */
78struct atl1_ring_header {
79 void *desc; /* virtual address */
80 dma_addr_t dma; /* physical address*/
81 unsigned int size; /* length in bytes */
82};
83
84/*
85 * atl1_buffer is wrapper around a pointer to a socket buffer
86 * so a DMA handle can be stored along with the skb
87 */
88struct atl1_buffer {
89 struct sk_buff *skb; /* socket buffer */
90 u16 length; /* rx buffer length */
91 u16 alloced; /* 1 if skb allocated */
92 dma_addr_t dma;
93};
94
95/* transmit packet descriptor (tpd) ring */
96struct atl1_tpd_ring {
97 void *desc; /* descriptor ring virtual address */
98 dma_addr_t dma; /* descriptor ring physical address */
99 u16 size; /* descriptor ring length in bytes */
100 u16 count; /* number of descriptors in the ring */
101 u16 hw_idx; /* hardware index */
102 atomic_t next_to_clean;
103 atomic_t next_to_use;
104 struct atl1_buffer *buffer_info;
105};
106
107/* receive free descriptor (rfd) ring */
108struct atl1_rfd_ring {
109 void *desc; /* descriptor ring virtual address */
110 dma_addr_t dma; /* descriptor ring physical address */
111 u16 size; /* descriptor ring length in bytes */
112 u16 count; /* number of descriptors in the ring */
113 atomic_t next_to_use;
114 u16 next_to_clean;
115 struct atl1_buffer *buffer_info;
116};
117
118/* receive return descriptor (rrd) ring */
119struct atl1_rrd_ring {
120 void *desc; /* descriptor ring virtual address */
121 dma_addr_t dma; /* descriptor ring physical address */
122 unsigned int size; /* descriptor ring length in bytes */
123 u16 count; /* number of descriptors in the ring */
124 u16 next_to_use;
125 atomic_t next_to_clean;
126};
127
128/* coalescing message block (cmb) */
129struct atl1_cmb {
130 struct coals_msg_block *cmb;
131 dma_addr_t dma;
132};
133
134/* statistics message block (smb) */
135struct atl1_smb {
136 struct stats_msg_block *smb;
137 dma_addr_t dma;
138};
139
140/* Statistics counters */
141struct atl1_sft_stats {
142 u64 rx_packets;
143 u64 tx_packets;
144 u64 rx_bytes;
145 u64 tx_bytes;
146 u64 multicast;
147 u64 collisions;
148 u64 rx_errors;
149 u64 rx_length_errors;
150 u64 rx_crc_errors;
151 u64 rx_frame_errors;
152 u64 rx_fifo_errors;
153 u64 rx_missed_errors;
154 u64 tx_errors;
155 u64 tx_fifo_errors;
156 u64 tx_aborted_errors;
157 u64 tx_window_errors;
158 u64 tx_carrier_errors;
159 u64 tx_pause; /* num pause packets transmitted. */
160 u64 excecol; /* num tx packets w/ excessive collisions. */
161 u64 deffer; /* num tx packets deferred */
162 u64 scc; /* num packets subsequently transmitted
163 * successfully w/ single prior collision. */
164 u64 mcc; /* num packets subsequently transmitted
165 * successfully w/ multiple prior collisions. */
166 u64 latecol; /* num tx packets w/ late collisions. */
167 u64 tx_underun; /* num tx packets aborted due to transmit
168 * FIFO underrun, or TRD FIFO underrun */
169 u64 tx_trunc; /* num tx packets truncated due to size
170 * exceeding MTU, regardless whether truncated
171 * by the chip or not. (The name doesn't really
172 * reflect the meaning in this case.) */
173 u64 rx_pause; /* num Pause packets received. */
174 u64 rx_rrd_ov;
175 u64 rx_trunc;
176};
177
178/* hardware structure */
179struct atl1_hw {
180 u8 __iomem *hw_addr;
181 struct atl1_adapter *back;
182 enum atl1_dma_order dma_ord;
183 enum atl1_dma_rcb rcb_value;
184 enum atl1_dma_req_block dmar_block;
185 enum atl1_dma_req_block dmaw_block;
186 u8 preamble_len;
187 u8 max_retry; /* Retransmission maximum, after which the
188 * packet will be discarded */
189 u8 jam_ipg; /* IPG to start JAM for collision based flow
190 * control in half-duplex mode. In units of
191 * 8-bit time */
192 u8 ipgt; /* Desired back to back inter-packet gap.
193 * The default is 96-bit time */
194 u8 min_ifg; /* Minimum number of IFG to enforce in between
195 * receive frames. Frame gap below such IFP
196 * is dropped */
197 u8 ipgr1; /* 64bit Carrier-Sense window */
198 u8 ipgr2; /* 96-bit IPG window */
199 u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned
200 * burst. Each TPD is 16 bytes long */
201 u8 rfd_burst; /* Number of RFD to prefetch in cache-aligned
202 * burst. Each RFD is 12 bytes long */
203 u8 rfd_fetch_gap;
204 u8 rrd_burst; /* Threshold number of RRDs that can be retired
205 * in a burst. Each RRD is 16 bytes long */
206 u8 tpd_fetch_th;
207 u8 tpd_fetch_gap;
208 u16 tx_jumbo_task_th;
209 u16 txf_burst; /* Number of data bytes to read in a cache-
210 * aligned burst. Each SRAM entry is 8 bytes */
211 u16 rx_jumbo_th; /* Jumbo packet size for non-VLAN packet. VLAN
212 * packets should add 4 bytes */
213 u16 rx_jumbo_lkah;
214 u16 rrd_ret_timer; /* RRD retirement timer. Decrement by 1 after
215 * every 512ns passes. */
216 u16 lcol; /* Collision Window */
217
218 u16 cmb_tpd;
219 u16 cmb_rrd;
220 u16 cmb_rx_timer;
221 u16 cmb_tx_timer;
222 u32 smb_timer;
223 u16 media_type;
224 u16 autoneg_advertised;
225
226 u16 mii_autoneg_adv_reg;
227 u16 mii_1000t_ctrl_reg;
228
229 u32 max_frame_size;
230 u32 min_frame_size;
231
232 u16 dev_rev;
233
234 /* spi flash */
235 u8 flash_vendor;
236
237 u8 mac_addr[ETH_ALEN];
238 u8 perm_mac_addr[ETH_ALEN];
239
240 bool phy_configured;
241};
242
243struct atl1_adapter {
244 struct net_device *netdev;
245 struct pci_dev *pdev;
246 struct net_device_stats net_stats;
247 struct atl1_sft_stats soft_stats;
248 struct vlan_group *vlgrp;
249 u32 rx_buffer_len;
250 u32 wol;
251 u16 link_speed;
252 u16 link_duplex;
253 spinlock_t lock;
254 struct work_struct tx_timeout_task;
255 struct work_struct link_chg_task;
256 struct work_struct pcie_dma_to_rst_task;
257 struct timer_list watchdog_timer;
258 struct timer_list phy_config_timer;
259 bool phy_timer_pending;
260
261 /* all descriptor rings' memory */
262 struct atl1_ring_header ring_header;
263
264 /* TX */
265 struct atl1_tpd_ring tpd_ring;
266 spinlock_t mb_lock;
267
268 /* RX */
269 struct atl1_rfd_ring rfd_ring;
270 struct atl1_rrd_ring rrd_ring;
271 u64 hw_csum_err;
272 u64 hw_csum_good;
273
274 u16 imt; /* interrupt moderator timer (2us resolution */
275 u16 ict; /* interrupt clear timer (2us resolution */
276 struct mii_if_info mii; /* MII interface info */
277
278 /* structs defined in atl1_hw.h */
279 u32 bd_number; /* board number */
280 bool pci_using_64;
281 struct atl1_hw hw;
282 struct atl1_smb smb;
283 struct atl1_cmb cmb;
284};
285
286#endif /* _ATL1_H_ */
diff --git a/drivers/net/atl1/atl1_ethtool.c b/drivers/net/atl1/atl1_ethtool.c
deleted file mode 100644
index 68a83be843ab..000000000000
--- a/drivers/net/atl1/atl1_ethtool.c
+++ /dev/null
@@ -1,505 +0,0 @@
1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
5 *
6 * Derived from Intel e1000 driver
7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/types.h>
25#include <linux/pci.h>
26#include <linux/ethtool.h>
27#include <linux/netdevice.h>
28#include <linux/mii.h>
29#include <asm/uaccess.h>
30
31#include "atl1.h"
32
33struct atl1_stats {
34 char stat_string[ETH_GSTRING_LEN];
35 int sizeof_stat;
36 int stat_offset;
37};
38
39#define ATL1_STAT(m) sizeof(((struct atl1_adapter *)0)->m), \
40 offsetof(struct atl1_adapter, m)
41
42static struct atl1_stats atl1_gstrings_stats[] = {
43 {"rx_packets", ATL1_STAT(soft_stats.rx_packets)},
44 {"tx_packets", ATL1_STAT(soft_stats.tx_packets)},
45 {"rx_bytes", ATL1_STAT(soft_stats.rx_bytes)},
46 {"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)},
47 {"rx_errors", ATL1_STAT(soft_stats.rx_errors)},
48 {"tx_errors", ATL1_STAT(soft_stats.tx_errors)},
49 {"rx_dropped", ATL1_STAT(net_stats.rx_dropped)},
50 {"tx_dropped", ATL1_STAT(net_stats.tx_dropped)},
51 {"multicast", ATL1_STAT(soft_stats.multicast)},
52 {"collisions", ATL1_STAT(soft_stats.collisions)},
53 {"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)},
54 {"rx_over_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
55 {"rx_crc_errors", ATL1_STAT(soft_stats.rx_crc_errors)},
56 {"rx_frame_errors", ATL1_STAT(soft_stats.rx_frame_errors)},
57 {"rx_fifo_errors", ATL1_STAT(soft_stats.rx_fifo_errors)},
58 {"rx_missed_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
59 {"tx_aborted_errors", ATL1_STAT(soft_stats.tx_aborted_errors)},
60 {"tx_carrier_errors", ATL1_STAT(soft_stats.tx_carrier_errors)},
61 {"tx_fifo_errors", ATL1_STAT(soft_stats.tx_fifo_errors)},
62 {"tx_window_errors", ATL1_STAT(soft_stats.tx_window_errors)},
63 {"tx_abort_exce_coll", ATL1_STAT(soft_stats.excecol)},
64 {"tx_abort_late_coll", ATL1_STAT(soft_stats.latecol)},
65 {"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)},
66 {"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)},
67 {"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)},
68 {"tx_underun", ATL1_STAT(soft_stats.tx_underun)},
69 {"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)},
70 {"tx_pause", ATL1_STAT(soft_stats.tx_pause)},
71 {"rx_pause", ATL1_STAT(soft_stats.rx_pause)},
72 {"rx_rrd_ov", ATL1_STAT(soft_stats.rx_rrd_ov)},
73 {"rx_trunc", ATL1_STAT(soft_stats.rx_trunc)}
74};
75
76static void atl1_get_ethtool_stats(struct net_device *netdev,
77 struct ethtool_stats *stats, u64 *data)
78{
79 struct atl1_adapter *adapter = netdev_priv(netdev);
80 int i;
81 char *p;
82
83 for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
84 p = (char *)adapter+atl1_gstrings_stats[i].stat_offset;
85 data[i] = (atl1_gstrings_stats[i].sizeof_stat ==
86 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
87 }
88
89}
90
91static int atl1_get_sset_count(struct net_device *netdev, int sset)
92{
93 switch (sset) {
94 case ETH_SS_STATS:
95 return ARRAY_SIZE(atl1_gstrings_stats);
96 default:
97 return -EOPNOTSUPP;
98 }
99}
100
101static int atl1_get_settings(struct net_device *netdev,
102 struct ethtool_cmd *ecmd)
103{
104 struct atl1_adapter *adapter = netdev_priv(netdev);
105 struct atl1_hw *hw = &adapter->hw;
106
107 ecmd->supported = (SUPPORTED_10baseT_Half |
108 SUPPORTED_10baseT_Full |
109 SUPPORTED_100baseT_Half |
110 SUPPORTED_100baseT_Full |
111 SUPPORTED_1000baseT_Full |
112 SUPPORTED_Autoneg | SUPPORTED_TP);
113 ecmd->advertising = ADVERTISED_TP;
114 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
115 hw->media_type == MEDIA_TYPE_1000M_FULL) {
116 ecmd->advertising |= ADVERTISED_Autoneg;
117 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR) {
118 ecmd->advertising |= ADVERTISED_Autoneg;
119 ecmd->advertising |=
120 (ADVERTISED_10baseT_Half |
121 ADVERTISED_10baseT_Full |
122 ADVERTISED_100baseT_Half |
123 ADVERTISED_100baseT_Full |
124 ADVERTISED_1000baseT_Full);
125 }
126 else
127 ecmd->advertising |= (ADVERTISED_1000baseT_Full);
128 }
129 ecmd->port = PORT_TP;
130 ecmd->phy_address = 0;
131 ecmd->transceiver = XCVR_INTERNAL;
132
133 if (netif_carrier_ok(adapter->netdev)) {
134 u16 link_speed, link_duplex;
135 atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
136 ecmd->speed = link_speed;
137 if (link_duplex == FULL_DUPLEX)
138 ecmd->duplex = DUPLEX_FULL;
139 else
140 ecmd->duplex = DUPLEX_HALF;
141 } else {
142 ecmd->speed = -1;
143 ecmd->duplex = -1;
144 }
145 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
146 hw->media_type == MEDIA_TYPE_1000M_FULL)
147 ecmd->autoneg = AUTONEG_ENABLE;
148 else
149 ecmd->autoneg = AUTONEG_DISABLE;
150
151 return 0;
152}
153
154static int atl1_set_settings(struct net_device *netdev,
155 struct ethtool_cmd *ecmd)
156{
157 struct atl1_adapter *adapter = netdev_priv(netdev);
158 struct atl1_hw *hw = &adapter->hw;
159 u16 phy_data;
160 int ret_val = 0;
161 u16 old_media_type = hw->media_type;
162
163 if (netif_running(adapter->netdev)) {
164 dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n");
165 atl1_down(adapter);
166 }
167
168 if (ecmd->autoneg == AUTONEG_ENABLE)
169 hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
170 else {
171 if (ecmd->speed == SPEED_1000) {
172 if (ecmd->duplex != DUPLEX_FULL) {
173 dev_warn(&adapter->pdev->dev,
174 "can't force to 1000M half duplex\n");
175 ret_val = -EINVAL;
176 goto exit_sset;
177 }
178 hw->media_type = MEDIA_TYPE_1000M_FULL;
179 } else if (ecmd->speed == SPEED_100) {
180 if (ecmd->duplex == DUPLEX_FULL) {
181 hw->media_type = MEDIA_TYPE_100M_FULL;
182 } else
183 hw->media_type = MEDIA_TYPE_100M_HALF;
184 } else {
185 if (ecmd->duplex == DUPLEX_FULL)
186 hw->media_type = MEDIA_TYPE_10M_FULL;
187 else
188 hw->media_type = MEDIA_TYPE_10M_HALF;
189 }
190 }
191 switch (hw->media_type) {
192 case MEDIA_TYPE_AUTO_SENSOR:
193 ecmd->advertising =
194 ADVERTISED_10baseT_Half |
195 ADVERTISED_10baseT_Full |
196 ADVERTISED_100baseT_Half |
197 ADVERTISED_100baseT_Full |
198 ADVERTISED_1000baseT_Full |
199 ADVERTISED_Autoneg | ADVERTISED_TP;
200 break;
201 case MEDIA_TYPE_1000M_FULL:
202 ecmd->advertising =
203 ADVERTISED_1000baseT_Full |
204 ADVERTISED_Autoneg | ADVERTISED_TP;
205 break;
206 default:
207 ecmd->advertising = 0;
208 break;
209 }
210 if (atl1_phy_setup_autoneg_adv(hw)) {
211 ret_val = -EINVAL;
212 dev_warn(&adapter->pdev->dev,
213 "invalid ethtool speed/duplex setting\n");
214 goto exit_sset;
215 }
216 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
217 hw->media_type == MEDIA_TYPE_1000M_FULL)
218 phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
219 else {
220 switch (hw->media_type) {
221 case MEDIA_TYPE_100M_FULL:
222 phy_data =
223 MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
224 MII_CR_RESET;
225 break;
226 case MEDIA_TYPE_100M_HALF:
227 phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
228 break;
229 case MEDIA_TYPE_10M_FULL:
230 phy_data =
231 MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
232 break;
233 default: /* MEDIA_TYPE_10M_HALF: */
234 phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
235 break;
236 }
237 }
238 atl1_write_phy_reg(hw, MII_BMCR, phy_data);
239exit_sset:
240 if (ret_val)
241 hw->media_type = old_media_type;
242
243 if (netif_running(adapter->netdev)) {
244 dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n");
245 atl1_up(adapter);
246 } else if (!ret_val) {
247 dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n");
248 atl1_reset(adapter);
249 }
250 return ret_val;
251}
252
253static void atl1_get_drvinfo(struct net_device *netdev,
254 struct ethtool_drvinfo *drvinfo)
255{
256 struct atl1_adapter *adapter = netdev_priv(netdev);
257
258 strncpy(drvinfo->driver, atl1_driver_name, sizeof(drvinfo->driver));
259 strncpy(drvinfo->version, atl1_driver_version,
260 sizeof(drvinfo->version));
261 strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
262 strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
263 sizeof(drvinfo->bus_info));
264 drvinfo->eedump_len = ATL1_EEDUMP_LEN;
265}
266
267static void atl1_get_wol(struct net_device *netdev,
268 struct ethtool_wolinfo *wol)
269{
270 struct atl1_adapter *adapter = netdev_priv(netdev);
271
272 wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
273 wol->wolopts = 0;
274 if (adapter->wol & ATL1_WUFC_EX)
275 wol->wolopts |= WAKE_UCAST;
276 if (adapter->wol & ATL1_WUFC_MC)
277 wol->wolopts |= WAKE_MCAST;
278 if (adapter->wol & ATL1_WUFC_BC)
279 wol->wolopts |= WAKE_BCAST;
280 if (adapter->wol & ATL1_WUFC_MAG)
281 wol->wolopts |= WAKE_MAGIC;
282 return;
283}
284
285static int atl1_set_wol(struct net_device *netdev,
286 struct ethtool_wolinfo *wol)
287{
288 struct atl1_adapter *adapter = netdev_priv(netdev);
289
290 if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
291 return -EOPNOTSUPP;
292 adapter->wol = 0;
293 if (wol->wolopts & WAKE_UCAST)
294 adapter->wol |= ATL1_WUFC_EX;
295 if (wol->wolopts & WAKE_MCAST)
296 adapter->wol |= ATL1_WUFC_MC;
297 if (wol->wolopts & WAKE_BCAST)
298 adapter->wol |= ATL1_WUFC_BC;
299 if (wol->wolopts & WAKE_MAGIC)
300 adapter->wol |= ATL1_WUFC_MAG;
301 return 0;
302}
303
304static void atl1_get_ringparam(struct net_device *netdev,
305 struct ethtool_ringparam *ring)
306{
307 struct atl1_adapter *adapter = netdev_priv(netdev);
308 struct atl1_tpd_ring *txdr = &adapter->tpd_ring;
309 struct atl1_rfd_ring *rxdr = &adapter->rfd_ring;
310
311 ring->rx_max_pending = ATL1_MAX_RFD;
312 ring->tx_max_pending = ATL1_MAX_TPD;
313 ring->rx_mini_max_pending = 0;
314 ring->rx_jumbo_max_pending = 0;
315 ring->rx_pending = rxdr->count;
316 ring->tx_pending = txdr->count;
317 ring->rx_mini_pending = 0;
318 ring->rx_jumbo_pending = 0;
319}
320
321static int atl1_set_ringparam(struct net_device *netdev,
322 struct ethtool_ringparam *ring)
323{
324 struct atl1_adapter *adapter = netdev_priv(netdev);
325 struct atl1_tpd_ring *tpdr = &adapter->tpd_ring;
326 struct atl1_rrd_ring *rrdr = &adapter->rrd_ring;
327 struct atl1_rfd_ring *rfdr = &adapter->rfd_ring;
328
329 struct atl1_tpd_ring tpd_old, tpd_new;
330 struct atl1_rfd_ring rfd_old, rfd_new;
331 struct atl1_rrd_ring rrd_old, rrd_new;
332 struct atl1_ring_header rhdr_old, rhdr_new;
333 int err;
334
335 tpd_old = adapter->tpd_ring;
336 rfd_old = adapter->rfd_ring;
337 rrd_old = adapter->rrd_ring;
338 rhdr_old = adapter->ring_header;
339
340 if (netif_running(adapter->netdev))
341 atl1_down(adapter);
342
343 rfdr->count = (u16) max(ring->rx_pending, (u32) ATL1_MIN_RFD);
344 rfdr->count = rfdr->count > ATL1_MAX_RFD ? ATL1_MAX_RFD :
345 rfdr->count;
346 rfdr->count = (rfdr->count + 3) & ~3;
347 rrdr->count = rfdr->count;
348
349 tpdr->count = (u16) max(ring->tx_pending, (u32) ATL1_MIN_TPD);
350 tpdr->count = tpdr->count > ATL1_MAX_TPD ? ATL1_MAX_TPD :
351 tpdr->count;
352 tpdr->count = (tpdr->count + 3) & ~3;
353
354 if (netif_running(adapter->netdev)) {
355 /* try to get new resources before deleting old */
356 err = atl1_setup_ring_resources(adapter);
357 if (err)
358 goto err_setup_ring;
359
360 /*
361 * save the new, restore the old in order to free it,
362 * then restore the new back again
363 */
364
365 rfd_new = adapter->rfd_ring;
366 rrd_new = adapter->rrd_ring;
367 tpd_new = adapter->tpd_ring;
368 rhdr_new = adapter->ring_header;
369 adapter->rfd_ring = rfd_old;
370 adapter->rrd_ring = rrd_old;
371 adapter->tpd_ring = tpd_old;
372 adapter->ring_header = rhdr_old;
373 atl1_free_ring_resources(adapter);
374 adapter->rfd_ring = rfd_new;
375 adapter->rrd_ring = rrd_new;
376 adapter->tpd_ring = tpd_new;
377 adapter->ring_header = rhdr_new;
378
379 err = atl1_up(adapter);
380 if (err)
381 return err;
382 }
383 return 0;
384
385err_setup_ring:
386 adapter->rfd_ring = rfd_old;
387 adapter->rrd_ring = rrd_old;
388 adapter->tpd_ring = tpd_old;
389 adapter->ring_header = rhdr_old;
390 atl1_up(adapter);
391 return err;
392}
393
394static void atl1_get_pauseparam(struct net_device *netdev,
395 struct ethtool_pauseparam *epause)
396{
397 struct atl1_adapter *adapter = netdev_priv(netdev);
398 struct atl1_hw *hw = &adapter->hw;
399
400 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
401 hw->media_type == MEDIA_TYPE_1000M_FULL) {
402 epause->autoneg = AUTONEG_ENABLE;
403 } else {
404 epause->autoneg = AUTONEG_DISABLE;
405 }
406 epause->rx_pause = 1;
407 epause->tx_pause = 1;
408}
409
410static int atl1_set_pauseparam(struct net_device *netdev,
411 struct ethtool_pauseparam *epause)
412{
413 struct atl1_adapter *adapter = netdev_priv(netdev);
414 struct atl1_hw *hw = &adapter->hw;
415
416 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
417 hw->media_type == MEDIA_TYPE_1000M_FULL) {
418 epause->autoneg = AUTONEG_ENABLE;
419 } else {
420 epause->autoneg = AUTONEG_DISABLE;
421 }
422
423 epause->rx_pause = 1;
424 epause->tx_pause = 1;
425
426 return 0;
427}
428
429static u32 atl1_get_rx_csum(struct net_device *netdev)
430{
431 return 1;
432}
433
434static void atl1_get_strings(struct net_device *netdev, u32 stringset,
435 u8 *data)
436{
437 u8 *p = data;
438 int i;
439
440 switch (stringset) {
441 case ETH_SS_STATS:
442 for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
443 memcpy(p, atl1_gstrings_stats[i].stat_string,
444 ETH_GSTRING_LEN);
445 p += ETH_GSTRING_LEN;
446 }
447 break;
448 }
449}
450
451static int atl1_nway_reset(struct net_device *netdev)
452{
453 struct atl1_adapter *adapter = netdev_priv(netdev);
454 struct atl1_hw *hw = &adapter->hw;
455
456 if (netif_running(netdev)) {
457 u16 phy_data;
458 atl1_down(adapter);
459
460 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
461 hw->media_type == MEDIA_TYPE_1000M_FULL) {
462 phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
463 } else {
464 switch (hw->media_type) {
465 case MEDIA_TYPE_100M_FULL:
466 phy_data = MII_CR_FULL_DUPLEX |
467 MII_CR_SPEED_100 | MII_CR_RESET;
468 break;
469 case MEDIA_TYPE_100M_HALF:
470 phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
471 break;
472 case MEDIA_TYPE_10M_FULL:
473 phy_data = MII_CR_FULL_DUPLEX |
474 MII_CR_SPEED_10 | MII_CR_RESET;
475 break;
476 default: /* MEDIA_TYPE_10M_HALF */
477 phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
478 }
479 }
480 atl1_write_phy_reg(hw, MII_BMCR, phy_data);
481 atl1_up(adapter);
482 }
483 return 0;
484}
485
486const struct ethtool_ops atl1_ethtool_ops = {
487 .get_settings = atl1_get_settings,
488 .set_settings = atl1_set_settings,
489 .get_drvinfo = atl1_get_drvinfo,
490 .get_wol = atl1_get_wol,
491 .set_wol = atl1_set_wol,
492 .get_ringparam = atl1_get_ringparam,
493 .set_ringparam = atl1_set_ringparam,
494 .get_pauseparam = atl1_get_pauseparam,
495 .set_pauseparam = atl1_set_pauseparam,
496 .get_rx_csum = atl1_get_rx_csum,
497 .set_tx_csum = ethtool_op_set_tx_hw_csum,
498 .get_link = ethtool_op_get_link,
499 .set_sg = ethtool_op_set_sg,
500 .get_strings = atl1_get_strings,
501 .nway_reset = atl1_nway_reset,
502 .get_ethtool_stats = atl1_get_ethtool_stats,
503 .get_sset_count = atl1_get_sset_count,
504 .set_tso = ethtool_op_set_tso,
505};
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
deleted file mode 100644
index 9d3bd22e3a82..000000000000
--- a/drivers/net/atl1/atl1_hw.c
+++ /dev/null
@@ -1,720 +0,0 @@
1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
5 *
6 * Derived from Intel e1000 driver
7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/types.h>
25#include <linux/pci.h>
26#include <linux/delay.h>
27#include <linux/if_vlan.h>
28#include <linux/etherdevice.h>
29#include <linux/crc32.h>
30#include <asm/byteorder.h>
31
32#include "atl1.h"
33
34/*
35 * Reset the transmit and receive units; mask and clear all interrupts.
36 * hw - Struct containing variables accessed by shared code
37 * return : ATL1_SUCCESS or idle status (if error)
38 */
39s32 atl1_reset_hw(struct atl1_hw *hw)
40{
41 struct pci_dev *pdev = hw->back->pdev;
42 u32 icr;
43 int i;
44
45 /*
46 * Clear Interrupt mask to stop board from generating
47 * interrupts & Clear any pending interrupt events
48 */
49 /*
50 * iowrite32(0, hw->hw_addr + REG_IMR);
51 * iowrite32(0xffffffff, hw->hw_addr + REG_ISR);
52 */
53
54 /*
55 * Issue Soft Reset to the MAC. This will reset the chip's
56 * transmit, receive, DMA. It will not effect
57 * the current PCI configuration. The global reset bit is self-
58 * clearing, and should clear within a microsecond.
59 */
60 iowrite32(MASTER_CTRL_SOFT_RST, hw->hw_addr + REG_MASTER_CTRL);
61 ioread32(hw->hw_addr + REG_MASTER_CTRL);
62
63 iowrite16(1, hw->hw_addr + REG_GPHY_ENABLE);
64 ioread16(hw->hw_addr + REG_GPHY_ENABLE);
65
66 msleep(1); /* delay about 1ms */
67
68 /* Wait at least 10ms for All module to be Idle */
69 for (i = 0; i < 10; i++) {
70 icr = ioread32(hw->hw_addr + REG_IDLE_STATUS);
71 if (!icr)
72 break;
73 msleep(1); /* delay 1 ms */
74 cpu_relax(); /* FIXME: is this still the right way to do this? */
75 }
76
77 if (icr) {
78 dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
79 return icr;
80 }
81
82 return ATL1_SUCCESS;
83}
84
85/* function about EEPROM
86 *
87 * check_eeprom_exist
88 * return 0 if eeprom exist
89 */
90static int atl1_check_eeprom_exist(struct atl1_hw *hw)
91{
92 u32 value;
93 value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
94 if (value & SPI_FLASH_CTRL_EN_VPD) {
95 value &= ~SPI_FLASH_CTRL_EN_VPD;
96 iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
97 }
98
99 value = ioread16(hw->hw_addr + REG_PCIE_CAP_LIST);
100 return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
101}
102
103static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value)
104{
105 int i;
106 u32 control;
107
108 if (offset & 3)
109 return false; /* address do not align */
110
111 iowrite32(0, hw->hw_addr + REG_VPD_DATA);
112 control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
113 iowrite32(control, hw->hw_addr + REG_VPD_CAP);
114 ioread32(hw->hw_addr + REG_VPD_CAP);
115
116 for (i = 0; i < 10; i++) {
117 msleep(2);
118 control = ioread32(hw->hw_addr + REG_VPD_CAP);
119 if (control & VPD_CAP_VPD_FLAG)
120 break;
121 }
122 if (control & VPD_CAP_VPD_FLAG) {
123 *p_value = ioread32(hw->hw_addr + REG_VPD_DATA);
124 return true;
125 }
126 return false; /* timeout */
127}
128
129/*
130 * Reads the value from a PHY register
131 * hw - Struct containing variables accessed by shared code
132 * reg_addr - address of the PHY register to read
133 */
134s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
135{
136 u32 val;
137 int i;
138
139 val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
140 MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
141 MDIO_CLK_SEL_SHIFT;
142 iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
143 ioread32(hw->hw_addr + REG_MDIO_CTRL);
144
145 for (i = 0; i < MDIO_WAIT_TIMES; i++) {
146 udelay(2);
147 val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
148 if (!(val & (MDIO_START | MDIO_BUSY)))
149 break;
150 }
151 if (!(val & (MDIO_START | MDIO_BUSY))) {
152 *phy_data = (u16) val;
153 return ATL1_SUCCESS;
154 }
155 return ATL1_ERR_PHY;
156}
157
158#define CUSTOM_SPI_CS_SETUP 2
159#define CUSTOM_SPI_CLK_HI 2
160#define CUSTOM_SPI_CLK_LO 2
161#define CUSTOM_SPI_CS_HOLD 2
162#define CUSTOM_SPI_CS_HI 3
163
164static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
165{
166 int i;
167 u32 value;
168
169 iowrite32(0, hw->hw_addr + REG_SPI_DATA);
170 iowrite32(addr, hw->hw_addr + REG_SPI_ADDR);
171
172 value = SPI_FLASH_CTRL_WAIT_READY |
173 (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) <<
174 SPI_FLASH_CTRL_CS_SETUP_SHIFT | (CUSTOM_SPI_CLK_HI &
175 SPI_FLASH_CTRL_CLK_HI_MASK) <<
176 SPI_FLASH_CTRL_CLK_HI_SHIFT | (CUSTOM_SPI_CLK_LO &
177 SPI_FLASH_CTRL_CLK_LO_MASK) <<
178 SPI_FLASH_CTRL_CLK_LO_SHIFT | (CUSTOM_SPI_CS_HOLD &
179 SPI_FLASH_CTRL_CS_HOLD_MASK) <<
180 SPI_FLASH_CTRL_CS_HOLD_SHIFT | (CUSTOM_SPI_CS_HI &
181 SPI_FLASH_CTRL_CS_HI_MASK) <<
182 SPI_FLASH_CTRL_CS_HI_SHIFT | (1 & SPI_FLASH_CTRL_INS_MASK) <<
183 SPI_FLASH_CTRL_INS_SHIFT;
184
185 iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
186
187 value |= SPI_FLASH_CTRL_START;
188 iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
189 ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
190
191 for (i = 0; i < 10; i++) {
192 msleep(1); /* 1ms */
193 value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
194 if (!(value & SPI_FLASH_CTRL_START))
195 break;
196 }
197
198 if (value & SPI_FLASH_CTRL_START)
199 return false;
200
201 *buf = ioread32(hw->hw_addr + REG_SPI_DATA);
202
203 return true;
204}
205
206/*
207 * get_permanent_address
208 * return 0 if get valid mac address,
209 */
210static int atl1_get_permanent_address(struct atl1_hw *hw)
211{
212 u32 addr[2];
213 u32 i, control;
214 u16 reg;
215 u8 eth_addr[ETH_ALEN];
216 bool key_valid;
217
218 if (is_valid_ether_addr(hw->perm_mac_addr))
219 return 0;
220
221 /* init */
222 addr[0] = addr[1] = 0;
223
224 if (!atl1_check_eeprom_exist(hw)) { /* eeprom exist */
225 reg = 0;
226 key_valid = false;
227 /* Read out all EEPROM content */
228 i = 0;
229 while (1) {
230 if (atl1_read_eeprom(hw, i + 0x100, &control)) {
231 if (key_valid) {
232 if (reg == REG_MAC_STA_ADDR)
233 addr[0] = control;
234 else if (reg == (REG_MAC_STA_ADDR + 4))
235 addr[1] = control;
236 key_valid = false;
237 } else if ((control & 0xff) == 0x5A) {
238 key_valid = true;
239 reg = (u16) (control >> 16);
240 } else
241 break; /* assume data end while encount an invalid KEYWORD */
242 } else
243 break; /* read error */
244 i += 4;
245 }
246
247 *(u32 *) &eth_addr[2] = swab32(addr[0]);
248 *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
249 if (is_valid_ether_addr(eth_addr)) {
250 memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
251 return 0;
252 }
253 return 1;
254 }
255
256 /* see if SPI FLAGS exist ? */
257 addr[0] = addr[1] = 0;
258 reg = 0;
259 key_valid = false;
260 i = 0;
261 while (1) {
262 if (atl1_spi_read(hw, i + 0x1f000, &control)) {
263 if (key_valid) {
264 if (reg == REG_MAC_STA_ADDR)
265 addr[0] = control;
266 else if (reg == (REG_MAC_STA_ADDR + 4))
267 addr[1] = control;
268 key_valid = false;
269 } else if ((control & 0xff) == 0x5A) {
270 key_valid = true;
271 reg = (u16) (control >> 16);
272 } else
273 break; /* data end */
274 } else
275 break; /* read error */
276 i += 4;
277 }
278
279 *(u32 *) &eth_addr[2] = swab32(addr[0]);
280 *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
281 if (is_valid_ether_addr(eth_addr)) {
282 memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
283 return 0;
284 }
285
286 /*
287 * On some motherboards, the MAC address is written by the
288 * BIOS directly to the MAC register during POST, and is
289 * not stored in eeprom. If all else thus far has failed
290 * to fetch the permanent MAC address, try reading it directly.
291 */
292 addr[0] = ioread32(hw->hw_addr + REG_MAC_STA_ADDR);
293 addr[1] = ioread16(hw->hw_addr + (REG_MAC_STA_ADDR + 4));
294 *(u32 *) &eth_addr[2] = swab32(addr[0]);
295 *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
296 if (is_valid_ether_addr(eth_addr)) {
297 memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
298 return 0;
299 }
300
301 return 1;
302}
303
304/*
305 * Reads the adapter's MAC address from the EEPROM
306 * hw - Struct containing variables accessed by shared code
307 */
308s32 atl1_read_mac_addr(struct atl1_hw *hw)
309{
310 u16 i;
311
312 if (atl1_get_permanent_address(hw))
313 random_ether_addr(hw->perm_mac_addr);
314
315 for (i = 0; i < ETH_ALEN; i++)
316 hw->mac_addr[i] = hw->perm_mac_addr[i];
317 return ATL1_SUCCESS;
318}
319
320/*
321 * Hashes an address to determine its location in the multicast table
322 * hw - Struct containing variables accessed by shared code
323 * mc_addr - the multicast address to hash
324 *
325 * atl1_hash_mc_addr
326 * purpose
327 * set hash value for a multicast address
328 * hash calcu processing :
329 * 1. calcu 32bit CRC for multicast address
330 * 2. reverse crc with MSB to LSB
331 */
332u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
333{
334 u32 crc32, value = 0;
335 int i;
336
337 crc32 = ether_crc_le(6, mc_addr);
338 for (i = 0; i < 32; i++)
339 value |= (((crc32 >> i) & 1) << (31 - i));
340
341 return value;
342}
343
344/*
345 * Sets the bit in the multicast table corresponding to the hash value.
346 * hw - Struct containing variables accessed by shared code
347 * hash_value - Multicast address hash value
348 */
349void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
350{
351 u32 hash_bit, hash_reg;
352 u32 mta;
353
354 /*
355 * The HASH Table is a register array of 2 32-bit registers.
356 * It is treated like an array of 64 bits. We want to set
357 * bit BitArray[hash_value]. So we figure out what register
358 * the bit is in, read it, OR in the new bit, then write
359 * back the new value. The register is determined by the
360 * upper 7 bits of the hash value and the bit within that
361 * register are determined by the lower 5 bits of the value.
362 */
363 hash_reg = (hash_value >> 31) & 0x1;
364 hash_bit = (hash_value >> 26) & 0x1F;
365 mta = ioread32((hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
366 mta |= (1 << hash_bit);
367 iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
368}
369
370/*
371 * Writes a value to a PHY register
372 * hw - Struct containing variables accessed by shared code
373 * reg_addr - address of the PHY register to write
374 * data - data to write to the PHY
375 */
376s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data)
377{
378 int i;
379 u32 val;
380
381 val = ((u32) (phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
382 (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
383 MDIO_SUP_PREAMBLE |
384 MDIO_START | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
385 iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
386 ioread32(hw->hw_addr + REG_MDIO_CTRL);
387
388 for (i = 0; i < MDIO_WAIT_TIMES; i++) {
389 udelay(2);
390 val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
391 if (!(val & (MDIO_START | MDIO_BUSY)))
392 break;
393 }
394
395 if (!(val & (MDIO_START | MDIO_BUSY)))
396 return ATL1_SUCCESS;
397
398 return ATL1_ERR_PHY;
399}
400
401/*
402 * Make L001's PHY out of Power Saving State (bug)
403 * hw - Struct containing variables accessed by shared code
404 * when power on, L001's PHY always on Power saving State
405 * (Gigabit Link forbidden)
406 */
407static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
408{
409 s32 ret;
410 ret = atl1_write_phy_reg(hw, 29, 0x0029);
411 if (ret)
412 return ret;
413 return atl1_write_phy_reg(hw, 30, 0);
414}
415
416/*
417 *TODO: do something or get rid of this
418 */
419s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
420{
421/* s32 ret_val;
422 * u16 phy_data;
423 */
424
425/*
426 ret_val = atl1_write_phy_reg(hw, ...);
427 ret_val = atl1_write_phy_reg(hw, ...);
428 ....
429*/
430 return ATL1_SUCCESS;
431}
432
433/*
434 * Resets the PHY and make all config validate
435 * hw - Struct containing variables accessed by shared code
436 *
437 * Sets bit 15 and 12 of the MII Control regiser (for F001 bug)
438 */
439static s32 atl1_phy_reset(struct atl1_hw *hw)
440{
441 struct pci_dev *pdev = hw->back->pdev;
442 s32 ret_val;
443 u16 phy_data;
444
445 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
446 hw->media_type == MEDIA_TYPE_1000M_FULL)
447 phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
448 else {
449 switch (hw->media_type) {
450 case MEDIA_TYPE_100M_FULL:
451 phy_data =
452 MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
453 MII_CR_RESET;
454 break;
455 case MEDIA_TYPE_100M_HALF:
456 phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
457 break;
458 case MEDIA_TYPE_10M_FULL:
459 phy_data =
460 MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
461 break;
462 default: /* MEDIA_TYPE_10M_HALF: */
463 phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
464 break;
465 }
466 }
467
468 ret_val = atl1_write_phy_reg(hw, MII_BMCR, phy_data);
469 if (ret_val) {
470 u32 val;
471 int i;
472 /* pcie serdes link may be down! */
473 dev_dbg(&pdev->dev, "pcie phy link down\n");
474
475 for (i = 0; i < 25; i++) {
476 msleep(1);
477 val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
478 if (!(val & (MDIO_START | MDIO_BUSY)))
479 break;
480 }
481
482 if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
483 dev_warn(&pdev->dev, "pcie link down at least 25ms\n");
484 return ret_val;
485 }
486 }
487 return ATL1_SUCCESS;
488}
489
490/*
491 * Configures PHY autoneg and flow control advertisement settings
492 * hw - Struct containing variables accessed by shared code
493 */
494s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
495{
496 s32 ret_val;
497 s16 mii_autoneg_adv_reg;
498 s16 mii_1000t_ctrl_reg;
499
500 /* Read the MII Auto-Neg Advertisement Register (Address 4). */
501 mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
502
503 /* Read the MII 1000Base-T Control Register (Address 9). */
504 mii_1000t_ctrl_reg = MII_AT001_CR_1000T_DEFAULT_CAP_MASK;
505
506 /*
507 * First we clear all the 10/100 mb speed bits in the Auto-Neg
508 * Advertisement Register (Address 4) and the 1000 mb speed bits in
509 * the 1000Base-T Control Register (Address 9).
510 */
511 mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
512 mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK;
513
514 /*
515 * Need to parse media_type and set up
516 * the appropriate PHY registers.
517 */
518 switch (hw->media_type) {
519 case MEDIA_TYPE_AUTO_SENSOR:
520 mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS |
521 MII_AR_10T_FD_CAPS |
522 MII_AR_100TX_HD_CAPS |
523 MII_AR_100TX_FD_CAPS);
524 mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS;
525 break;
526
527 case MEDIA_TYPE_1000M_FULL:
528 mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS;
529 break;
530
531 case MEDIA_TYPE_100M_FULL:
532 mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
533 break;
534
535 case MEDIA_TYPE_100M_HALF:
536 mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
537 break;
538
539 case MEDIA_TYPE_10M_FULL:
540 mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
541 break;
542
543 default:
544 mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
545 break;
546 }
547
548 /* flow control fixed to enable all */
549 mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
550
551 hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
552 hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg;
553
554 ret_val = atl1_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
555 if (ret_val)
556 return ret_val;
557
558 ret_val = atl1_write_phy_reg(hw, MII_AT001_CR, mii_1000t_ctrl_reg);
559 if (ret_val)
560 return ret_val;
561
562 return ATL1_SUCCESS;
563}
564
565/*
566 * Configures link settings.
567 * hw - Struct containing variables accessed by shared code
568 * Assumes the hardware has previously been reset and the
569 * transmitter and receiver are not enabled.
570 */
571static s32 atl1_setup_link(struct atl1_hw *hw)
572{
573 struct pci_dev *pdev = hw->back->pdev;
574 s32 ret_val;
575
576 /*
577 * Options:
578 * PHY will advertise value(s) parsed from
579 * autoneg_advertised and fc
580 * no matter what autoneg is , We will not wait link result.
581 */
582 ret_val = atl1_phy_setup_autoneg_adv(hw);
583 if (ret_val) {
584 dev_dbg(&pdev->dev, "error setting up autonegotiation\n");
585 return ret_val;
586 }
587 /* SW.Reset , En-Auto-Neg if needed */
588 ret_val = atl1_phy_reset(hw);
589 if (ret_val) {
590 dev_dbg(&pdev->dev, "error resetting phy\n");
591 return ret_val;
592 }
593 hw->phy_configured = true;
594 return ret_val;
595}
596
597static struct atl1_spi_flash_dev flash_table[] = {
598/* MFR_NAME WRSR READ PRGM WREN WRDI RDSR RDID SECTOR_ERASE CHIP_ERASE */
599 {"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62},
600 {"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60},
601 {"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7},
602};
603
604static void atl1_init_flash_opcode(struct atl1_hw *hw)
605{
606 if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
607 hw->flash_vendor = 0; /* ATMEL */
608
609 /* Init OP table */
610 iowrite8(flash_table[hw->flash_vendor].cmd_program,
611 hw->hw_addr + REG_SPI_FLASH_OP_PROGRAM);
612 iowrite8(flash_table[hw->flash_vendor].cmd_sector_erase,
613 hw->hw_addr + REG_SPI_FLASH_OP_SC_ERASE);
614 iowrite8(flash_table[hw->flash_vendor].cmd_chip_erase,
615 hw->hw_addr + REG_SPI_FLASH_OP_CHIP_ERASE);
616 iowrite8(flash_table[hw->flash_vendor].cmd_rdid,
617 hw->hw_addr + REG_SPI_FLASH_OP_RDID);
618 iowrite8(flash_table[hw->flash_vendor].cmd_wren,
619 hw->hw_addr + REG_SPI_FLASH_OP_WREN);
620 iowrite8(flash_table[hw->flash_vendor].cmd_rdsr,
621 hw->hw_addr + REG_SPI_FLASH_OP_RDSR);
622 iowrite8(flash_table[hw->flash_vendor].cmd_wrsr,
623 hw->hw_addr + REG_SPI_FLASH_OP_WRSR);
624 iowrite8(flash_table[hw->flash_vendor].cmd_read,
625 hw->hw_addr + REG_SPI_FLASH_OP_READ);
626}
627
628/*
629 * Performs basic configuration of the adapter.
630 * hw - Struct containing variables accessed by shared code
631 * Assumes that the controller has previously been reset and is in a
632 * post-reset uninitialized state. Initializes multicast table,
633 * and Calls routines to setup link
634 * Leaves the transmit and receive units disabled and uninitialized.
635 */
636s32 atl1_init_hw(struct atl1_hw *hw)
637{
638 u32 ret_val = 0;
639
640 /* Zero out the Multicast HASH table */
641 iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
642 /* clear the old settings from the multicast hash table */
643 iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
644
645 atl1_init_flash_opcode(hw);
646
647 if (!hw->phy_configured) {
648 /* enable GPHY LinkChange Interrrupt */
649 ret_val = atl1_write_phy_reg(hw, 18, 0xC00);
650 if (ret_val)
651 return ret_val;
652 /* make PHY out of power-saving state */
653 ret_val = atl1_phy_leave_power_saving(hw);
654 if (ret_val)
655 return ret_val;
656 /* Call a subroutine to configure the link */
657 ret_val = atl1_setup_link(hw);
658 }
659 return ret_val;
660}
661
662/*
663 * Detects the current speed and duplex settings of the hardware.
664 * hw - Struct containing variables accessed by shared code
665 * speed - Speed of the connection
666 * duplex - Duplex setting of the connection
667 */
668s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
669{
670 struct pci_dev *pdev = hw->back->pdev;
671 s32 ret_val;
672 u16 phy_data;
673
674 /* ; --- Read PHY Specific Status Register (17) */
675 ret_val = atl1_read_phy_reg(hw, MII_AT001_PSSR, &phy_data);
676 if (ret_val)
677 return ret_val;
678
679 if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED))
680 return ATL1_ERR_PHY_RES;
681
682 switch (phy_data & MII_AT001_PSSR_SPEED) {
683 case MII_AT001_PSSR_1000MBS:
684 *speed = SPEED_1000;
685 break;
686 case MII_AT001_PSSR_100MBS:
687 *speed = SPEED_100;
688 break;
689 case MII_AT001_PSSR_10MBS:
690 *speed = SPEED_10;
691 break;
692 default:
693 dev_dbg(&pdev->dev, "error getting speed\n");
694 return ATL1_ERR_PHY_SPEED;
695 break;
696 }
697 if (phy_data & MII_AT001_PSSR_DPLX)
698 *duplex = FULL_DUPLEX;
699 else
700 *duplex = HALF_DUPLEX;
701
702 return ATL1_SUCCESS;
703}
704
705void atl1_set_mac_addr(struct atl1_hw *hw)
706{
707 u32 value;
708 /*
709 * 00-0B-6A-F6-00-DC
710 * 0: 6AF600DC 1: 000B
711 * low dword
712 */
713 value = (((u32) hw->mac_addr[2]) << 24) |
714 (((u32) hw->mac_addr[3]) << 16) |
715 (((u32) hw->mac_addr[4]) << 8) | (((u32) hw->mac_addr[5]));
716 iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR);
717 /* high dword */
718 value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1]));
719 iowrite32(value, (hw->hw_addr + REG_MAC_STA_ADDR) + (1 << 2));
720}
diff --git a/drivers/net/atl1/atl1_hw.h b/drivers/net/atl1/atl1_hw.h
deleted file mode 100644
index 939aa0f53f6e..000000000000
--- a/drivers/net/atl1/atl1_hw.h
+++ /dev/null
@@ -1,946 +0,0 @@
1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
5 *
6 * Derived from Intel e1000 driver
7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 * There are a lot of defines in here that are unused and/or have cryptic
24 * names. Please leave them alone, as they're the closest thing we have
25 * to a spec from Attansic at present. *ahem* -- CHS
26 */
27
28#ifndef _ATL1_HW_H_
29#define _ATL1_HW_H_
30
31#include <linux/types.h>
32#include <linux/mii.h>
33
34struct atl1_adapter;
35struct atl1_hw;
36
37/* function prototypes needed by multiple files */
38s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw);
39s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data);
40s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex);
41s32 atl1_read_mac_addr(struct atl1_hw *hw);
42s32 atl1_init_hw(struct atl1_hw *hw);
43s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex);
44s32 atl1_set_speed_and_duplex(struct atl1_hw *hw, u16 speed, u16 duplex);
45u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
46void atl1_hash_set(struct atl1_hw *hw, u32 hash_value);
47s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data);
48void atl1_set_mac_addr(struct atl1_hw *hw);
49s32 atl1_phy_enter_power_saving(struct atl1_hw *hw);
50s32 atl1_reset_hw(struct atl1_hw *hw);
51void atl1_check_options(struct atl1_adapter *adapter);
52
53/* register definitions */
54#define REG_PCIE_CAP_LIST 0x58
55
56#define REG_VPD_CAP 0x6C
57#define VPD_CAP_ID_MASK 0xff
58#define VPD_CAP_ID_SHIFT 0
59#define VPD_CAP_NEXT_PTR_MASK 0xFF
60#define VPD_CAP_NEXT_PTR_SHIFT 8
61#define VPD_CAP_VPD_ADDR_MASK 0x7FFF
62#define VPD_CAP_VPD_ADDR_SHIFT 16
63#define VPD_CAP_VPD_FLAG 0x80000000
64
65#define REG_VPD_DATA 0x70
66
67#define REG_SPI_FLASH_CTRL 0x200
68#define SPI_FLASH_CTRL_STS_NON_RDY 0x1
69#define SPI_FLASH_CTRL_STS_WEN 0x2
70#define SPI_FLASH_CTRL_STS_WPEN 0x80
71#define SPI_FLASH_CTRL_DEV_STS_MASK 0xFF
72#define SPI_FLASH_CTRL_DEV_STS_SHIFT 0
73#define SPI_FLASH_CTRL_INS_MASK 0x7
74#define SPI_FLASH_CTRL_INS_SHIFT 8
75#define SPI_FLASH_CTRL_START 0x800
76#define SPI_FLASH_CTRL_EN_VPD 0x2000
77#define SPI_FLASH_CTRL_LDSTART 0x8000
78#define SPI_FLASH_CTRL_CS_HI_MASK 0x3
79#define SPI_FLASH_CTRL_CS_HI_SHIFT 16
80#define SPI_FLASH_CTRL_CS_HOLD_MASK 0x3
81#define SPI_FLASH_CTRL_CS_HOLD_SHIFT 18
82#define SPI_FLASH_CTRL_CLK_LO_MASK 0x3
83#define SPI_FLASH_CTRL_CLK_LO_SHIFT 20
84#define SPI_FLASH_CTRL_CLK_HI_MASK 0x3
85#define SPI_FLASH_CTRL_CLK_HI_SHIFT 22
86#define SPI_FLASH_CTRL_CS_SETUP_MASK 0x3
87#define SPI_FLASH_CTRL_CS_SETUP_SHIFT 24
88#define SPI_FLASH_CTRL_EROM_PGSZ_MASK 0x3
89#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26
90#define SPI_FLASH_CTRL_WAIT_READY 0x10000000
91
92#define REG_SPI_ADDR 0x204
93
94#define REG_SPI_DATA 0x208
95
96#define REG_SPI_FLASH_CONFIG 0x20C
97#define SPI_FLASH_CONFIG_LD_ADDR_MASK 0xFFFFFF
98#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0
99#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3
100#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24
101#define SPI_FLASH_CONFIG_LD_EXIST 0x4000000
102
103#define REG_SPI_FLASH_OP_PROGRAM 0x210
104#define REG_SPI_FLASH_OP_SC_ERASE 0x211
105#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212
106#define REG_SPI_FLASH_OP_RDID 0x213
107#define REG_SPI_FLASH_OP_WREN 0x214
108#define REG_SPI_FLASH_OP_RDSR 0x215
109#define REG_SPI_FLASH_OP_WRSR 0x216
110#define REG_SPI_FLASH_OP_READ 0x217
111
112#define REG_TWSI_CTRL 0x218
113#define TWSI_CTRL_LD_OFFSET_MASK 0xFF
114#define TWSI_CTRL_LD_OFFSET_SHIFT 0
115#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7
116#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8
117#define TWSI_CTRL_SW_LDSTART 0x800
118#define TWSI_CTRL_HW_LDSTART 0x1000
119#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F
120#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15
121#define TWSI_CTRL_LD_EXIST 0x400000
122#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3
123#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23
124#define TWSI_CTRL_FREQ_SEL_100K 0
125#define TWSI_CTRL_FREQ_SEL_200K 1
126#define TWSI_CTRL_FREQ_SEL_300K 2
127#define TWSI_CTRL_FREQ_SEL_400K 3
128#define TWSI_CTRL_SMB_SLV_ADDR
129#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3
130#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24
131
132#define REG_PCIE_DEV_MISC_CTRL 0x21C
133#define PCIE_DEV_MISC_CTRL_EXT_PIPE 0x2
134#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1
135#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4
136#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN 0x8
137#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN 0x10
138
139/* Selene Master Control Register */
140#define REG_MASTER_CTRL 0x1400
141#define MASTER_CTRL_SOFT_RST 0x1
142#define MASTER_CTRL_MTIMER_EN 0x2
143#define MASTER_CTRL_ITIMER_EN 0x4
144#define MASTER_CTRL_MANUAL_INT 0x8
145#define MASTER_CTRL_REV_NUM_SHIFT 16
146#define MASTER_CTRL_REV_NUM_MASK 0xff
147#define MASTER_CTRL_DEV_ID_SHIFT 24
148#define MASTER_CTRL_DEV_ID_MASK 0xff
149
150/* Timer Initial Value Register */
151#define REG_MANUAL_TIMER_INIT 0x1404
152
153/* IRQ ModeratorTimer Initial Value Register */
154#define REG_IRQ_MODU_TIMER_INIT 0x1408
155
156#define REG_GPHY_ENABLE 0x140C
157
158/* IRQ Anti-Lost Timer Initial Value Register */
159#define REG_CMBDISDMA_TIMER 0x140E
160
161/* Block IDLE Status Register */
162#define REG_IDLE_STATUS 0x1410
163#define IDLE_STATUS_RXMAC 1
164#define IDLE_STATUS_TXMAC 2
165#define IDLE_STATUS_RXQ 4
166#define IDLE_STATUS_TXQ 8
167#define IDLE_STATUS_DMAR 0x10
168#define IDLE_STATUS_DMAW 0x20
169#define IDLE_STATUS_SMB 0x40
170#define IDLE_STATUS_CMB 0x80
171
172/* MDIO Control Register */
173#define REG_MDIO_CTRL 0x1414
174#define MDIO_DATA_MASK 0xffff
175#define MDIO_DATA_SHIFT 0
176#define MDIO_REG_ADDR_MASK 0x1f
177#define MDIO_REG_ADDR_SHIFT 16
178#define MDIO_RW 0x200000
179#define MDIO_SUP_PREAMBLE 0x400000
180#define MDIO_START 0x800000
181#define MDIO_CLK_SEL_SHIFT 24
182#define MDIO_CLK_25_4 0
183#define MDIO_CLK_25_6 2
184#define MDIO_CLK_25_8 3
185#define MDIO_CLK_25_10 4
186#define MDIO_CLK_25_14 5
187#define MDIO_CLK_25_20 6
188#define MDIO_CLK_25_28 7
189#define MDIO_BUSY 0x8000000
190#define MDIO_WAIT_TIMES 30
191
192/* MII PHY Status Register */
193#define REG_PHY_STATUS 0x1418
194
195/* BIST Control and Status Register0 (for the Packet Memory) */
196#define REG_BIST0_CTRL 0x141c
197#define BIST0_NOW 0x1
198#define BIST0_SRAM_FAIL 0x2
199#define BIST0_FUSE_FLAG 0x4
200#define REG_BIST1_CTRL 0x1420
201#define BIST1_NOW 0x1
202#define BIST1_SRAM_FAIL 0x2
203#define BIST1_FUSE_FLAG 0x4
204
205/* MAC Control Register */
206#define REG_MAC_CTRL 0x1480
207#define MAC_CTRL_TX_EN 1
208#define MAC_CTRL_RX_EN 2
209#define MAC_CTRL_TX_FLOW 4
210#define MAC_CTRL_RX_FLOW 8
211#define MAC_CTRL_LOOPBACK 0x10
212#define MAC_CTRL_DUPLX 0x20
213#define MAC_CTRL_ADD_CRC 0x40
214#define MAC_CTRL_PAD 0x80
215#define MAC_CTRL_LENCHK 0x100
216#define MAC_CTRL_HUGE_EN 0x200
217#define MAC_CTRL_PRMLEN_SHIFT 10
218#define MAC_CTRL_PRMLEN_MASK 0xf
219#define MAC_CTRL_RMV_VLAN 0x4000
220#define MAC_CTRL_PROMIS_EN 0x8000
221#define MAC_CTRL_TX_PAUSE 0x10000
222#define MAC_CTRL_SCNT 0x20000
223#define MAC_CTRL_SRST_TX 0x40000
224#define MAC_CTRL_TX_SIMURST 0x80000
225#define MAC_CTRL_SPEED_SHIFT 20
226#define MAC_CTRL_SPEED_MASK 0x300000
227#define MAC_CTRL_SPEED_1000 2
228#define MAC_CTRL_SPEED_10_100 1
229#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000
230#define MAC_CTRL_TX_HUGE 0x800000
231#define MAC_CTRL_RX_CHKSUM_EN 0x1000000
232#define MAC_CTRL_MC_ALL_EN 0x2000000
233#define MAC_CTRL_BC_EN 0x4000000
234#define MAC_CTRL_DBG 0x8000000
235
236/* MAC IPG/IFG Control Register */
237#define REG_MAC_IPG_IFG 0x1484
238#define MAC_IPG_IFG_IPGT_SHIFT 0
239#define MAC_IPG_IFG_IPGT_MASK 0x7f
240#define MAC_IPG_IFG_MIFG_SHIFT 8
241#define MAC_IPG_IFG_MIFG_MASK 0xff
242#define MAC_IPG_IFG_IPGR1_SHIFT 16
243#define MAC_IPG_IFG_IPGR1_MASK 0x7f
244#define MAC_IPG_IFG_IPGR2_SHIFT 24
245#define MAC_IPG_IFG_IPGR2_MASK 0x7f
246
247/* MAC STATION ADDRESS */
248#define REG_MAC_STA_ADDR 0x1488
249
250/* Hash table for multicast address */
251#define REG_RX_HASH_TABLE 0x1490
252
253/* MAC Half-Duplex Control Register */
254#define REG_MAC_HALF_DUPLX_CTRL 0x1498
255#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0
256#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff
257#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
258#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf
259#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000
260#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000
261#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000
262#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000
263#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20
264#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf
265#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24
266#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf
267
268/* Maximum Frame Length Control Register */
269#define REG_MTU 0x149c
270
271/* Wake-On-Lan control register */
272#define REG_WOL_CTRL 0x14a0
273#define WOL_PATTERN_EN 0x00000001
274#define WOL_PATTERN_PME_EN 0x00000002
275#define WOL_MAGIC_EN 0x00000004
276#define WOL_MAGIC_PME_EN 0x00000008
277#define WOL_LINK_CHG_EN 0x00000010
278#define WOL_LINK_CHG_PME_EN 0x00000020
279#define WOL_PATTERN_ST 0x00000100
280#define WOL_MAGIC_ST 0x00000200
281#define WOL_LINKCHG_ST 0x00000400
282#define WOL_CLK_SWITCH_EN 0x00008000
283#define WOL_PT0_EN 0x00010000
284#define WOL_PT1_EN 0x00020000
285#define WOL_PT2_EN 0x00040000
286#define WOL_PT3_EN 0x00080000
287#define WOL_PT4_EN 0x00100000
288#define WOL_PT5_EN 0x00200000
289#define WOL_PT6_EN 0x00400000
290
291/* WOL Length ( 2 DWORD ) */
292#define REG_WOL_PATTERN_LEN 0x14a4
293#define WOL_PT_LEN_MASK 0x7f
294#define WOL_PT0_LEN_SHIFT 0
295#define WOL_PT1_LEN_SHIFT 8
296#define WOL_PT2_LEN_SHIFT 16
297#define WOL_PT3_LEN_SHIFT 24
298#define WOL_PT4_LEN_SHIFT 0
299#define WOL_PT5_LEN_SHIFT 8
300#define WOL_PT6_LEN_SHIFT 16
301
302/* Internal SRAM Partition Register */
303#define REG_SRAM_RFD_ADDR 0x1500
304#define REG_SRAM_RFD_LEN (REG_SRAM_RFD_ADDR+ 4)
305#define REG_SRAM_RRD_ADDR (REG_SRAM_RFD_ADDR+ 8)
306#define REG_SRAM_RRD_LEN (REG_SRAM_RFD_ADDR+12)
307#define REG_SRAM_TPD_ADDR (REG_SRAM_RFD_ADDR+16)
308#define REG_SRAM_TPD_LEN (REG_SRAM_RFD_ADDR+20)
309#define REG_SRAM_TRD_ADDR (REG_SRAM_RFD_ADDR+24)
310#define REG_SRAM_TRD_LEN (REG_SRAM_RFD_ADDR+28)
311#define REG_SRAM_RXF_ADDR (REG_SRAM_RFD_ADDR+32)
312#define REG_SRAM_RXF_LEN (REG_SRAM_RFD_ADDR+36)
313#define REG_SRAM_TXF_ADDR (REG_SRAM_RFD_ADDR+40)
314#define REG_SRAM_TXF_LEN (REG_SRAM_RFD_ADDR+44)
315#define REG_SRAM_TCPH_PATH_ADDR (REG_SRAM_RFD_ADDR+48)
316#define SRAM_TCPH_ADDR_MASK 0x0fff
317#define SRAM_TCPH_ADDR_SHIFT 0
318#define SRAM_PATH_ADDR_MASK 0x0fff
319#define SRAM_PATH_ADDR_SHIFT 16
320
321/* Load Ptr Register */
322#define REG_LOAD_PTR (REG_SRAM_RFD_ADDR+52)
323
324/* Descriptor Control register */
325#define REG_DESC_BASE_ADDR_HI 0x1540
326#define REG_DESC_RFD_ADDR_LO (REG_DESC_BASE_ADDR_HI+4)
327#define REG_DESC_RRD_ADDR_LO (REG_DESC_BASE_ADDR_HI+8)
328#define REG_DESC_TPD_ADDR_LO (REG_DESC_BASE_ADDR_HI+12)
329#define REG_DESC_CMB_ADDR_LO (REG_DESC_BASE_ADDR_HI+16)
330#define REG_DESC_SMB_ADDR_LO (REG_DESC_BASE_ADDR_HI+20)
331#define REG_DESC_RFD_RRD_RING_SIZE (REG_DESC_BASE_ADDR_HI+24)
332#define DESC_RFD_RING_SIZE_MASK 0x7ff
333#define DESC_RFD_RING_SIZE_SHIFT 0
334#define DESC_RRD_RING_SIZE_MASK 0x7ff
335#define DESC_RRD_RING_SIZE_SHIFT 16
336#define REG_DESC_TPD_RING_SIZE (REG_DESC_BASE_ADDR_HI+28)
337#define DESC_TPD_RING_SIZE_MASK 0x3ff
338#define DESC_TPD_RING_SIZE_SHIFT 0
339
340/* TXQ Control Register */
341#define REG_TXQ_CTRL 0x1580
342#define TXQ_CTRL_TPD_BURST_NUM_SHIFT 0
343#define TXQ_CTRL_TPD_BURST_NUM_MASK 0x1f
344#define TXQ_CTRL_EN 0x20
345#define TXQ_CTRL_ENH_MODE 0x40
346#define TXQ_CTRL_TPD_FETCH_TH_SHIFT 8
347#define TXQ_CTRL_TPD_FETCH_TH_MASK 0x3f
348#define TXQ_CTRL_TXF_BURST_NUM_SHIFT 16
349#define TXQ_CTRL_TXF_BURST_NUM_MASK 0xffff
350
351/* Jumbo packet Threshold for task offload */
352#define REG_TX_JUMBO_TASK_TH_TPD_IPG 0x1584
353#define TX_JUMBO_TASK_TH_MASK 0x7ff
354#define TX_JUMBO_TASK_TH_SHIFT 0
355#define TX_TPD_MIN_IPG_MASK 0x1f
356#define TX_TPD_MIN_IPG_SHIFT 16
357
358/* RXQ Control Register */
359#define REG_RXQ_CTRL 0x15a0
360#define RXQ_CTRL_RFD_BURST_NUM_SHIFT 0
361#define RXQ_CTRL_RFD_BURST_NUM_MASK 0xff
362#define RXQ_CTRL_RRD_BURST_THRESH_SHIFT 8
363#define RXQ_CTRL_RRD_BURST_THRESH_MASK 0xff
364#define RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT 16
365#define RXQ_CTRL_RFD_PREF_MIN_IPG_MASK 0x1f
366#define RXQ_CTRL_CUT_THRU_EN 0x40000000
367#define RXQ_CTRL_EN 0x80000000
368
369/* Rx jumbo packet threshold and rrd retirement timer */
370#define REG_RXQ_JMBOSZ_RRDTIM (REG_RXQ_CTRL+ 4)
371#define RXQ_JMBOSZ_TH_MASK 0x7ff
372#define RXQ_JMBOSZ_TH_SHIFT 0
373#define RXQ_JMBO_LKAH_MASK 0xf
374#define RXQ_JMBO_LKAH_SHIFT 11
375#define RXQ_RRD_TIMER_MASK 0xffff
376#define RXQ_RRD_TIMER_SHIFT 16
377
378/* RFD flow control register */
379#define REG_RXQ_RXF_PAUSE_THRESH (REG_RXQ_CTRL+ 8)
380#define RXQ_RXF_PAUSE_TH_HI_SHIFT 16
381#define RXQ_RXF_PAUSE_TH_HI_MASK 0xfff
382#define RXQ_RXF_PAUSE_TH_LO_SHIFT 0
383#define RXQ_RXF_PAUSE_TH_LO_MASK 0xfff
384
385/* RRD flow control register */
386#define REG_RXQ_RRD_PAUSE_THRESH (REG_RXQ_CTRL+12)
387#define RXQ_RRD_PAUSE_TH_HI_SHIFT 0
388#define RXQ_RRD_PAUSE_TH_HI_MASK 0xfff
389#define RXQ_RRD_PAUSE_TH_LO_SHIFT 16
390#define RXQ_RRD_PAUSE_TH_LO_MASK 0xfff
391
392/* DMA Engine Control Register */
393#define REG_DMA_CTRL 0x15c0
394#define DMA_CTRL_DMAR_IN_ORDER 0x1
395#define DMA_CTRL_DMAR_ENH_ORDER 0x2
396#define DMA_CTRL_DMAR_OUT_ORDER 0x4
397#define DMA_CTRL_RCB_VALUE 0x8
398#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4
399#define DMA_CTRL_DMAR_BURST_LEN_MASK 7
400#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7
401#define DMA_CTRL_DMAW_BURST_LEN_MASK 7
402#define DMA_CTRL_DMAR_EN 0x400
403#define DMA_CTRL_DMAW_EN 0x800
404
405/* CMB/SMB Control Register */
406#define REG_CSMB_CTRL 0x15d0
407#define CSMB_CTRL_CMB_NOW 1
408#define CSMB_CTRL_SMB_NOW 2
409#define CSMB_CTRL_CMB_EN 4
410#define CSMB_CTRL_SMB_EN 8
411
412/* CMB DMA Write Threshold Register */
413#define REG_CMB_WRITE_TH (REG_CSMB_CTRL+ 4)
414#define CMB_RRD_TH_SHIFT 0
415#define CMB_RRD_TH_MASK 0x7ff
416#define CMB_TPD_TH_SHIFT 16
417#define CMB_TPD_TH_MASK 0x7ff
418
419/* RX/TX count-down timer to trigger CMB-write. 2us resolution. */
420#define REG_CMB_WRITE_TIMER (REG_CSMB_CTRL+ 8)
421#define CMB_RX_TM_SHIFT 0
422#define CMB_RX_TM_MASK 0xffff
423#define CMB_TX_TM_SHIFT 16
424#define CMB_TX_TM_MASK 0xffff
425
426/* Number of packet received since last CMB write */
427#define REG_CMB_RX_PKT_CNT (REG_CSMB_CTRL+12)
428
429/* Number of packet transmitted since last CMB write */
430#define REG_CMB_TX_PKT_CNT (REG_CSMB_CTRL+16)
431
432/* SMB auto DMA timer register */
433#define REG_SMB_TIMER (REG_CSMB_CTRL+20)
434
435/* Mailbox Register */
436#define REG_MAILBOX 0x15f0
437#define MB_RFD_PROD_INDX_SHIFT 0
438#define MB_RFD_PROD_INDX_MASK 0x7ff
439#define MB_RRD_CONS_INDX_SHIFT 11
440#define MB_RRD_CONS_INDX_MASK 0x7ff
441#define MB_TPD_PROD_INDX_SHIFT 22
442#define MB_TPD_PROD_INDX_MASK 0x3ff
443
444/* Interrupt Status Register */
445#define REG_ISR 0x1600
446#define ISR_SMB 1
447#define ISR_TIMER 2
448#define ISR_MANUAL 4
449#define ISR_RXF_OV 8
450#define ISR_RFD_UNRUN 0x10
451#define ISR_RRD_OV 0x20
452#define ISR_TXF_UNRUN 0x40
453#define ISR_LINK 0x80
454#define ISR_HOST_RFD_UNRUN 0x100
455#define ISR_HOST_RRD_OV 0x200
456#define ISR_DMAR_TO_RST 0x400
457#define ISR_DMAW_TO_RST 0x800
458#define ISR_GPHY 0x1000
459#define ISR_RX_PKT 0x10000
460#define ISR_TX_PKT 0x20000
461#define ISR_TX_DMA 0x40000
462#define ISR_RX_DMA 0x80000
463#define ISR_CMB_RX 0x100000
464#define ISR_CMB_TX 0x200000
465#define ISR_MAC_RX 0x400000
466#define ISR_MAC_TX 0x800000
467#define ISR_UR_DETECTED 0x1000000
468#define ISR_FERR_DETECTED 0x2000000
469#define ISR_NFERR_DETECTED 0x4000000
470#define ISR_CERR_DETECTED 0x8000000
471#define ISR_PHY_LINKDOWN 0x10000000
472#define ISR_DIS_SMB 0x20000000
473#define ISR_DIS_DMA 0x40000000
474#define ISR_DIS_INT 0x80000000
475
476/* Interrupt Mask Register */
477#define REG_IMR 0x1604
478
479/* Normal Interrupt mask */
480#define IMR_NORMAL_MASK (\
481 ISR_SMB |\
482 ISR_GPHY |\
483 ISR_PHY_LINKDOWN|\
484 ISR_DMAR_TO_RST |\
485 ISR_DMAW_TO_RST |\
486 ISR_CMB_TX |\
487 ISR_CMB_RX )
488
489/* Debug Interrupt Mask (enable all interrupt) */
490#define IMR_DEBUG_MASK (\
491 ISR_SMB |\
492 ISR_TIMER |\
493 ISR_MANUAL |\
494 ISR_RXF_OV |\
495 ISR_RFD_UNRUN |\
496 ISR_RRD_OV |\
497 ISR_TXF_UNRUN |\
498 ISR_LINK |\
499 ISR_CMB_TX |\
500 ISR_CMB_RX |\
501 ISR_RX_PKT |\
502 ISR_TX_PKT |\
503 ISR_MAC_RX |\
504 ISR_MAC_TX )
505
506/* Interrupt Status Register */
507#define REG_RFD_RRD_IDX 0x1800
508#define REG_TPD_IDX 0x1804
509
510/* MII definition */
511/* PHY Common Register */
512#define MII_AT001_CR 0x09
513#define MII_AT001_SR 0x0A
514#define MII_AT001_ESR 0x0F
515#define MII_AT001_PSCR 0x10
516#define MII_AT001_PSSR 0x11
517
518/* PHY Control Register */
519#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
520#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
521#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
522#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
523#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
524#define MII_CR_POWER_DOWN 0x0800 /* Power down */
525#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
526#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
527#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
528#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
529#define MII_CR_SPEED_MASK 0x2040
530#define MII_CR_SPEED_1000 0x0040
531#define MII_CR_SPEED_100 0x2000
532#define MII_CR_SPEED_10 0x0000
533
534/* PHY Status Register */
535#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
536#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
537#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
538#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
539#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
540#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
541#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
542#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
543#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
544#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
545#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
546#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
547#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
548#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
549#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
550
551/* Link partner ability register. */
552#define MII_LPA_SLCT 0x001f /* Same as advertise selector */
553#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
554#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
555#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
556#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
557#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */
558#define MII_LPA_PAUSE 0x0400 /* PAUSE */
559#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */
560#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */
561#define MII_LPA_LPACK 0x4000 /* Link partner acked us */
562#define MII_LPA_NPAGE 0x8000 /* Next page bit */
563
564/* Autoneg Advertisement Register */
565#define MII_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */
566#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
567#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
568#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
569#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
570#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
571#define MII_AR_PAUSE 0x0400 /* Pause operation desired */
572#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
573#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
574#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */
575#define MII_AR_SPEED_MASK 0x01E0
576#define MII_AR_DEFAULT_CAP_MASK 0x0DE0
577
578/* 1000BASE-T Control Register */
579#define MII_AT001_CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
580#define MII_AT001_CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
581#define MII_AT001_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port, 0=DTE device */
582#define MII_AT001_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master, 0=Configure PHY as Slave */
583#define MII_AT001_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value, 0=Automatic Master/Slave config */
584#define MII_AT001_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
585#define MII_AT001_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
586#define MII_AT001_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
587#define MII_AT001_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
588#define MII_AT001_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
589#define MII_AT001_CR_1000T_SPEED_MASK 0x0300
590#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK 0x0300
591
592/* 1000BASE-T Status Register */
593#define MII_AT001_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
594#define MII_AT001_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
595#define MII_AT001_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
596#define MII_AT001_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
597#define MII_AT001_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */
598#define MII_AT001_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
599#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT 12
600#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT 13
601
602/* Extended Status Register */
603#define MII_AT001_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
604#define MII_AT001_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
605#define MII_AT001_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
606#define MII_AT001_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
607
608/* AT001 PHY Specific Control Register */
609#define MII_AT001_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
610#define MII_AT001_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
611#define MII_AT001_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
612#define MII_AT001_PSCR_MAC_POWERDOWN 0x0008
613#define MII_AT001_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, 0=CLK125 toggling */
614#define MII_AT001_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5, Manual MDI configuration */
615#define MII_AT001_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
616#define MII_AT001_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
617#define MII_AT001_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled all speeds. */
618#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE 0x0080 /* 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold), 0=Normal 10BASE-T RX Threshold */
619#define MII_AT001_PSCR_MII_5BIT_ENABLE 0x0100 /* 1=5-Bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */
620#define MII_AT001_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */
621#define MII_AT001_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
622#define MII_AT001_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
623#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT 1
624#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT 5
625#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
626
627/* AT001 PHY Specific Status Register */
628#define MII_AT001_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
629#define MII_AT001_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
630#define MII_AT001_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
631#define MII_AT001_PSSR_10MBS 0x0000 /* 00=10Mbs */
632#define MII_AT001_PSSR_100MBS 0x4000 /* 01=100Mbs */
633#define MII_AT001_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
634
635/* PCI Command Register Bit Definitions */
636#define PCI_REG_COMMAND 0x04 /* PCI Command Register */
637#define CMD_IO_SPACE 0x0001
638#define CMD_MEMORY_SPACE 0x0002
639#define CMD_BUS_MASTER 0x0004
640
641/* Wake Up Filter Control */
642#define ATL1_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
643#define ATL1_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
644#define ATL1_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
645#define ATL1_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
646#define ATL1_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
647
648/* Error Codes */
649#define ATL1_SUCCESS 0
650#define ATL1_ERR_EEPROM 1
651#define ATL1_ERR_PHY 2
652#define ATL1_ERR_CONFIG 3
653#define ATL1_ERR_PARAM 4
654#define ATL1_ERR_MAC_TYPE 5
655#define ATL1_ERR_PHY_TYPE 6
656#define ATL1_ERR_PHY_SPEED 7
657#define ATL1_ERR_PHY_RES 8
658
659#define SPEED_0 0xffff
660#define SPEED_10 10
661#define SPEED_100 100
662#define SPEED_1000 1000
663#define HALF_DUPLEX 1
664#define FULL_DUPLEX 2
665
666#define MEDIA_TYPE_AUTO_SENSOR 0
667#define MEDIA_TYPE_1000M_FULL 1
668#define MEDIA_TYPE_100M_FULL 2
669#define MEDIA_TYPE_100M_HALF 3
670#define MEDIA_TYPE_10M_FULL 4
671#define MEDIA_TYPE_10M_HALF 5
672
673#define ADVERTISE_10_HALF 0x0001
674#define ADVERTISE_10_FULL 0x0002
675#define ADVERTISE_100_HALF 0x0004
676#define ADVERTISE_100_FULL 0x0008
677#define ADVERTISE_1000_HALF 0x0010
678#define ADVERTISE_1000_FULL 0x0020
679#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
680#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds */
681#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds */
682
683#define MAX_JUMBO_FRAME_SIZE 0x2800
684
685#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
686#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
687
688/* For checksumming , the sum of all words in the EEPROM should equal 0xBABA */
689#define EEPROM_SUM 0xBABA
690
691#define ATL1_EEDUMP_LEN 48
692
693/* Statistics counters collected by the MAC */
694struct stats_msg_block {
695 /* rx */
696 u32 rx_ok; /* The number of good packet received. */
697 u32 rx_bcast; /* The number of good broadcast packet received. */
698 u32 rx_mcast; /* The number of good multicast packet received. */
699 u32 rx_pause; /* The number of Pause packet received. */
700 u32 rx_ctrl; /* The number of Control packet received other than Pause frame. */
701 u32 rx_fcs_err; /* The number of packets with bad FCS. */
702 u32 rx_len_err; /* The number of packets with mismatch of length field and actual size. */
703 u32 rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */
704 u32 rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */
705 u32 rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */
706 u32 rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */
707 u32 rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */
708 u32 rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */
709 u32 rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */
710 u32 rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
711 u32 rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
712 u32 rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
713 u32 rx_sz_ov; /* The number of good and bad packets received that are more than MTU size Å¡C truncated by Selene. */
714 u32 rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */
715 u32 rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */
716 u32 rx_align_err; /* Alignment Error */
717 u32 rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
718 u32 rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
719 u32 rx_err_addr; /* The number of packets dropped due to address filtering. */
720
721 /* tx */
722 u32 tx_ok; /* The number of good packet transmitted. */
723 u32 tx_bcast; /* The number of good broadcast packet transmitted. */
724 u32 tx_mcast; /* The number of good multicast packet transmitted. */
725 u32 tx_pause; /* The number of Pause packet transmitted. */
726 u32 tx_exc_defer; /* The number of packets transmitted with excessive deferral. */
727 u32 tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */
728 u32 tx_defer; /* The number of packets transmitted that is deferred. */
729 u32 tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */
730 u32 tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */
731 u32 tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
732 u32 tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
733 u32 tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
734 u32 tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
735 u32 tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
736 u32 tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
737 u32 tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */
738 u32 tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
739 u32 tx_late_col; /* The number of packets transmitted with late collisions. */
740 u32 tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */
741 u32 tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
742 u32 tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
743 u32 tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */
744 u32 tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */
745 u32 tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */
746 u32 tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */
747 u32 smb_updated; /* 1: SMB Updated. This is used by software as the indication of the statistics update.
748 * Software should clear this bit as soon as retrieving the statistics information. */
749};
750
751/* Coalescing Message Block */
752struct coals_msg_block {
753 u32 int_stats; /* interrupt status */
754 u16 rrd_prod_idx; /* TRD Producer Index. */
755 u16 rfd_cons_idx; /* RFD Consumer Index. */
756 u16 update; /* Selene sets this bit every time it DMA the CMB to host memory.
757 * Software supposes to clear this bit when CMB information is processed. */
758 u16 tpd_cons_idx; /* TPD Consumer Index. */
759};
760
761/* RRD descriptor */
762struct rx_return_desc {
763 u8 num_buf; /* Number of RFD buffers used by the received packet */
764 u8 resved;
765 u16 buf_indx; /* RFD Index of the first buffer */
766 union {
767 u32 valid;
768 struct {
769 u16 rx_chksum;
770 u16 pkt_size;
771 } xsum_sz;
772 } xsz;
773
774 u16 pkt_flg; /* Packet flags */
775 u16 err_flg; /* Error flags */
776 u16 resved2;
777 u16 vlan_tag; /* VLAN TAG */
778};
779
780#define PACKET_FLAG_ETH_TYPE 0x0080
781#define PACKET_FLAG_VLAN_INS 0x0100
782#define PACKET_FLAG_ERR 0x0200
783#define PACKET_FLAG_IPV4 0x0400
784#define PACKET_FLAG_UDP 0x0800
785#define PACKET_FLAG_TCP 0x1000
786#define PACKET_FLAG_BCAST 0x2000
787#define PACKET_FLAG_MCAST 0x4000
788#define PACKET_FLAG_PAUSE 0x8000
789
790#define ERR_FLAG_CRC 0x0001
791#define ERR_FLAG_CODE 0x0002
792#define ERR_FLAG_DRIBBLE 0x0004
793#define ERR_FLAG_RUNT 0x0008
794#define ERR_FLAG_OV 0x0010
795#define ERR_FLAG_TRUNC 0x0020
796#define ERR_FLAG_IP_CHKSUM 0x0040
797#define ERR_FLAG_L4_CHKSUM 0x0080
798#define ERR_FLAG_LEN 0x0100
799#define ERR_FLAG_DES_ADDR 0x0200
800
801/* RFD descriptor */
802struct rx_free_desc {
803 __le64 buffer_addr; /* Address of the descriptor's data buffer */
804 __le16 buf_len; /* Size of the receive buffer in host memory, in byte */
805 u16 coalese; /* Update consumer index to host after the reception of this frame */
806 /* __attribute__ ((packed)) is required */
807} __attribute__ ((packed));
808
809/* tsopu defines */
810#define TSO_PARAM_BUFLEN_MASK 0x3FFF
811#define TSO_PARAM_BUFLEN_SHIFT 0
812#define TSO_PARAM_DMAINT_MASK 0x0001
813#define TSO_PARAM_DMAINT_SHIFT 14
814#define TSO_PARAM_PKTNT_MASK 0x0001
815#define TSO_PARAM_PKTINT_SHIFT 15
816#define TSO_PARAM_VLANTAG_MASK 0xFFFF
817#define TSO_PARAM_VLAN_SHIFT 16
818
819/* tsopl defines */
820#define TSO_PARAM_EOP_MASK 0x0001
821#define TSO_PARAM_EOP_SHIFT 0
822#define TSO_PARAM_COALESCE_MASK 0x0001
823#define TSO_PARAM_COALESCE_SHIFT 1
824#define TSO_PARAM_INSVLAG_MASK 0x0001
825#define TSO_PARAM_INSVLAG_SHIFT 2
826#define TSO_PARAM_CUSTOMCKSUM_MASK 0x0001
827#define TSO_PARAM_CUSTOMCKSUM_SHIFT 3
828#define TSO_PARAM_SEGMENT_MASK 0x0001
829#define TSO_PARAM_SEGMENT_SHIFT 4
830#define TSO_PARAM_IPCKSUM_MASK 0x0001
831#define TSO_PARAM_IPCKSUM_SHIFT 5
832#define TSO_PARAM_TCPCKSUM_MASK 0x0001
833#define TSO_PARAM_TCPCKSUM_SHIFT 6
834#define TSO_PARAM_UDPCKSUM_MASK 0x0001
835#define TSO_PARAM_UDPCKSUM_SHIFT 7
836#define TSO_PARAM_VLANTAGGED_MASK 0x0001
837#define TSO_PARAM_VLANTAGGED_SHIFT 8
838#define TSO_PARAM_ETHTYPE_MASK 0x0001
839#define TSO_PARAM_ETHTYPE_SHIFT 9
840#define TSO_PARAM_IPHL_MASK 0x000F
841#define TSO_PARAM_IPHL_SHIFT 10
842#define TSO_PARAM_TCPHDRLEN_MASK 0x000F
843#define TSO_PARAM_TCPHDRLEN_SHIFT 14
844#define TSO_PARAM_HDRFLAG_MASK 0x0001
845#define TSO_PARAM_HDRFLAG_SHIFT 18
846#define TSO_PARAM_MSS_MASK 0x1FFF
847#define TSO_PARAM_MSS_SHIFT 19
848
849/* csumpu defines */
850#define CSUM_PARAM_BUFLEN_MASK 0x3FFF
851#define CSUM_PARAM_BUFLEN_SHIFT 0
852#define CSUM_PARAM_DMAINT_MASK 0x0001
853#define CSUM_PARAM_DMAINT_SHIFT 14
854#define CSUM_PARAM_PKTINT_MASK 0x0001
855#define CSUM_PARAM_PKTINT_SHIFT 15
856#define CSUM_PARAM_VALANTAG_MASK 0xFFFF
857#define CSUM_PARAM_VALAN_SHIFT 16
858
859/* csumpl defines*/
860#define CSUM_PARAM_EOP_MASK 0x0001
861#define CSUM_PARAM_EOP_SHIFT 0
862#define CSUM_PARAM_COALESCE_MASK 0x0001
863#define CSUM_PARAM_COALESCE_SHIFT 1
864#define CSUM_PARAM_INSVLAG_MASK 0x0001
865#define CSUM_PARAM_INSVLAG_SHIFT 2
866#define CSUM_PARAM_CUSTOMCKSUM_MASK 0x0001
867#define CSUM_PARAM_CUSTOMCKSUM_SHIFT 3
868#define CSUM_PARAM_SEGMENT_MASK 0x0001
869#define CSUM_PARAM_SEGMENT_SHIFT 4
870#define CSUM_PARAM_IPCKSUM_MASK 0x0001
871#define CSUM_PARAM_IPCKSUM_SHIFT 5
872#define CSUM_PARAM_TCPCKSUM_MASK 0x0001
873#define CSUM_PARAM_TCPCKSUM_SHIFT 6
874#define CSUM_PARAM_UDPCKSUM_MASK 0x0001
875#define CSUM_PARAM_UDPCKSUM_SHIFT 7
876#define CSUM_PARAM_VLANTAGGED_MASK 0x0001
877#define CSUM_PARAM_VLANTAGGED_SHIFT 8
878#define CSUM_PARAM_ETHTYPE_MASK 0x0001
879#define CSUM_PARAM_ETHTYPE_SHIFT 9
880#define CSUM_PARAM_IPHL_MASK 0x000F
881#define CSUM_PARAM_IPHL_SHIFT 10
882#define CSUM_PARAM_PLOADOFFSET_MASK 0x00FF
883#define CSUM_PARAM_PLOADOFFSET_SHIFT 16
884#define CSUM_PARAM_XSUMOFFSET_MASK 0x00FF
885#define CSUM_PARAM_XSUMOFFSET_SHIFT 24
886
887/* TPD descriptor */
888struct tso_param {
889 /* The order of these declarations is important -- don't change it */
890 u32 tsopu; /* tso_param upper word */
891 u32 tsopl; /* tso_param lower word */
892};
893
894struct csum_param {
895 /* The order of these declarations is important -- don't change it */
896 u32 csumpu; /* csum_param upper word */
897 u32 csumpl; /* csum_param lower word */
898};
899
900union tpd_descr {
901 u64 data;
902 struct csum_param csum;
903 struct tso_param tso;
904};
905
906struct tx_packet_desc {
907 __le64 buffer_addr;
908 union tpd_descr desc;
909};
910
911/* DMA Order Settings */
912enum atl1_dma_order {
913 atl1_dma_ord_in = 1,
914 atl1_dma_ord_enh = 2,
915 atl1_dma_ord_out = 4
916};
917
918enum atl1_dma_rcb {
919 atl1_rcb_64 = 0,
920 atl1_rcb_128 = 1
921};
922
923enum atl1_dma_req_block {
924 atl1_dma_req_128 = 0,
925 atl1_dma_req_256 = 1,
926 atl1_dma_req_512 = 2,
927 atl1_dma_req_1024 = 3,
928 atl1_dma_req_2048 = 4,
929 atl1_dma_req_4096 = 5
930};
931
932struct atl1_spi_flash_dev {
933 const char *manu_name; /* manufacturer id */
934 /* op-code */
935 u8 cmd_wrsr;
936 u8 cmd_read;
937 u8 cmd_program;
938 u8 cmd_wren;
939 u8 cmd_wrdi;
940 u8 cmd_rdsr;
941 u8 cmd_rdid;
942 u8 cmd_sector_erase;
943 u8 cmd_chip_erase;
944};
945
946#endif /* _ATL1_HW_H_ */
diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atl1/atl1_param.c
deleted file mode 100644
index 4246bb9bd50e..000000000000
--- a/drivers/net/atl1/atl1_param.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
5 *
6 * Derived from Intel e1000 driver
7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/types.h>
25#include <linux/moduleparam.h>
26#include <linux/pci.h>
27#include "atl1.h"
28
29/*
30 * This is the only thing that needs to be changed to adjust the
31 * maximum number of ports that the driver can manage.
32 */
33#define ATL1_MAX_NIC 4
34
35#define OPTION_UNSET -1
36#define OPTION_DISABLED 0
37#define OPTION_ENABLED 1
38
39#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }
40
41/*
42 * Interrupt Moderate Timer in units of 2 us
43 *
44 * Valid Range: 10-65535
45 *
46 * Default Value: 100 (200us)
47 */
48static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
49static int num_int_mod_timer = 0;
50module_param_array_named(int_mod_timer, int_mod_timer, int, &num_int_mod_timer, 0);
51MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
52
53/*
54 * flash_vendor
55 *
56 * Valid Range: 0-2
57 *
58 * 0 - Atmel
59 * 1 - SST
60 * 2 - ST
61 *
62 * Default Value: 0
63 */
64static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
65static int num_flash_vendor = 0;
66module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0);
67MODULE_PARM_DESC(flash_vendor, "SPI flash vendor");
68
69#define DEFAULT_INT_MOD_CNT 100 /* 200us */
70#define MAX_INT_MOD_CNT 65000
71#define MIN_INT_MOD_CNT 50
72
73#define FLASH_VENDOR_DEFAULT 0
74#define FLASH_VENDOR_MIN 0
75#define FLASH_VENDOR_MAX 2
76
77struct atl1_option {
78 enum { enable_option, range_option, list_option } type;
79 char *name;
80 char *err;
81 int def;
82 union {
83 struct { /* range_option info */
84 int min;
85 int max;
86 } r;
87 struct { /* list_option info */
88 int nr;
89 struct atl1_opt_list {
90 int i;
91 char *str;
92 } *p;
93 } l;
94 } arg;
95};
96
97static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, struct pci_dev *pdev)
98{
99 if (*value == OPTION_UNSET) {
100 *value = opt->def;
101 return 0;
102 }
103
104 switch (opt->type) {
105 case enable_option:
106 switch (*value) {
107 case OPTION_ENABLED:
108 dev_info(&pdev->dev, "%s enabled\n", opt->name);
109 return 0;
110 case OPTION_DISABLED:
111 dev_info(&pdev->dev, "%s disabled\n", opt->name);
112 return 0;
113 }
114 break;
115 case range_option:
116 if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
117 dev_info(&pdev->dev, "%s set to %i\n", opt->name,
118 *value);
119 return 0;
120 }
121 break;
122 case list_option:{
123 int i;
124 struct atl1_opt_list *ent;
125
126 for (i = 0; i < opt->arg.l.nr; i++) {
127 ent = &opt->arg.l.p[i];
128 if (*value == ent->i) {
129 if (ent->str[0] != '\0')
130 dev_info(&pdev->dev, "%s\n",
131 ent->str);
132 return 0;
133 }
134 }
135 }
136 break;
137
138 default:
139 break;
140 }
141
142 dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
143 opt->name, *value, opt->err);
144 *value = opt->def;
145 return -1;
146}
147
148/*
149 * atl1_check_options - Range Checking for Command Line Parameters
150 * @adapter: board private structure
151 *
152 * This routine checks all command line parameters for valid user
153 * input. If an invalid value is given, or if no user specified
154 * value exists, a default value is used. The final value is stored
155 * in a variable in the adapter structure.
156 */
157void __devinit atl1_check_options(struct atl1_adapter *adapter)
158{
159 struct pci_dev *pdev = adapter->pdev;
160 int bd = adapter->bd_number;
161 if (bd >= ATL1_MAX_NIC) {
162 dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
163 dev_notice(&pdev->dev, "using defaults for all values\n");
164 }
165 { /* Interrupt Moderate Timer */
166 struct atl1_option opt = {
167 .type = range_option,
168 .name = "Interrupt Moderator Timer",
169 .err = "using default of "
170 __MODULE_STRING(DEFAULT_INT_MOD_CNT),
171 .def = DEFAULT_INT_MOD_CNT,
172 .arg = {.r =
173 {.min = MIN_INT_MOD_CNT,.max = MAX_INT_MOD_CNT}}
174 };
175 int val;
176 if (num_int_mod_timer > bd) {
177 val = int_mod_timer[bd];
178 atl1_validate_option(&val, &opt, pdev);
179 adapter->imt = (u16) val;
180 } else
181 adapter->imt = (u16) (opt.def);
182 }
183
184 { /* Flash Vendor */
185 struct atl1_option opt = {
186 .type = range_option,
187 .name = "SPI Flash Vendor",
188 .err = "using default of "
189 __MODULE_STRING(FLASH_VENDOR_DEFAULT),
190 .def = DEFAULT_INT_MOD_CNT,
191 .arg = {.r =
192 {.min = FLASH_VENDOR_MIN,.max =
193 FLASH_VENDOR_MAX}}
194 };
195 int val;
196 if (num_flash_vendor > bd) {
197 val = flash_vendor[bd];
198 atl1_validate_option(&val, &opt, pdev);
199 adapter->hw.flash_vendor = (u8) val;
200 } else
201 adapter->hw.flash_vendor = (u8) (opt.def);
202 }
203}
diff --git a/drivers/net/atlx/Makefile b/drivers/net/atlx/Makefile
new file mode 100644
index 000000000000..ca45553a040d
--- /dev/null
+++ b/drivers/net/atlx/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_ATL1) += atl1.o
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atlx/atl1.c
index 129b8b3aa773..5586fc624688 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atlx/atl1.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. 2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 Chris Snook <csnook@redhat.com> 3 * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com> 4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
5 * 5 *
6 * Derived from Intel e1000 driver 6 * Derived from Intel e1000 driver
@@ -36,7 +36,6 @@
36 * A very incomplete list of things that need to be dealt with: 36 * A very incomplete list of things that need to be dealt with:
37 * 37 *
38 * TODO: 38 * TODO:
39 * Fix TSO; tx performance is horrible with TSO enabled.
40 * Wake on LAN. 39 * Wake on LAN.
41 * Add more ethtool functions. 40 * Add more ethtool functions.
42 * Fix abstruse irq enable/disable condition described here: 41 * Fix abstruse irq enable/disable condition described here:
@@ -50,51 +49,46 @@
50 * SMP torture testing 49 * SMP torture testing
51 */ 50 */
52 51
53#include <linux/types.h> 52#include <asm/atomic.h>
54#include <linux/netdevice.h> 53#include <asm/byteorder.h>
55#include <linux/pci.h> 54
56#include <linux/spinlock.h> 55#include <linux/compiler.h>
57#include <linux/slab.h> 56#include <linux/crc32.h>
58#include <linux/string.h> 57#include <linux/delay.h>
59#include <linux/skbuff.h> 58#include <linux/dma-mapping.h>
60#include <linux/etherdevice.h> 59#include <linux/etherdevice.h>
61#include <linux/if_vlan.h>
62#include <linux/if_ether.h>
63#include <linux/irqreturn.h>
64#include <linux/workqueue.h>
65#include <linux/timer.h>
66#include <linux/jiffies.h>
67#include <linux/hardirq.h> 60#include <linux/hardirq.h>
61#include <linux/if_ether.h>
62#include <linux/if_vlan.h>
63#include <linux/in.h>
68#include <linux/interrupt.h> 64#include <linux/interrupt.h>
65#include <linux/ip.h>
69#include <linux/irqflags.h> 66#include <linux/irqflags.h>
70#include <linux/dma-mapping.h> 67#include <linux/irqreturn.h>
68#include <linux/jiffies.h>
69#include <linux/mii.h>
70#include <linux/module.h>
71#include <linux/moduleparam.h>
71#include <linux/net.h> 72#include <linux/net.h>
73#include <linux/netdevice.h>
74#include <linux/pci.h>
75#include <linux/pci_ids.h>
72#include <linux/pm.h> 76#include <linux/pm.h>
73#include <linux/in.h> 77#include <linux/skbuff.h>
74#include <linux/ip.h> 78#include <linux/slab.h>
79#include <linux/spinlock.h>
80#include <linux/string.h>
75#include <linux/tcp.h> 81#include <linux/tcp.h>
76#include <linux/compiler.h> 82#include <linux/timer.h>
77#include <linux/delay.h> 83#include <linux/types.h>
78#include <linux/mii.h> 84#include <linux/workqueue.h>
79#include <net/checksum.h>
80 85
81#include <asm/atomic.h> 86#include <net/checksum.h>
82#include <asm/byteorder.h>
83 87
84#include "atl1.h" 88#include "atl1.h"
85 89
86#define DRIVER_VERSION "2.0.7" 90/* Temporary hack for merging atl1 and atl2 */
87 91#include "atlx.c"
88char atl1_driver_name[] = "atl1";
89static const char atl1_driver_string[] = "Attansic L1 Ethernet Network Driver";
90static const char atl1_copyright[] = "Copyright(c) 2005-2006 Attansic Corporation.";
91char atl1_driver_version[] = DRIVER_VERSION;
92
93MODULE_AUTHOR
94 ("Attansic Corporation <xiong_huang@attansic.com>, Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
95MODULE_DESCRIPTION("Attansic 1000M Ethernet Network Driver");
96MODULE_LICENSE("GPL");
97MODULE_VERSION(DRIVER_VERSION);
98 92
99/* 93/*
100 * atl1_pci_tbl - PCI Device ID Table 94 * atl1_pci_tbl - PCI Device ID Table
@@ -104,9 +98,720 @@ static const struct pci_device_id atl1_pci_tbl[] = {
104 /* required last entry */ 98 /* required last entry */
105 {0,} 99 {0,}
106}; 100};
107
108MODULE_DEVICE_TABLE(pci, atl1_pci_tbl); 101MODULE_DEVICE_TABLE(pci, atl1_pci_tbl);
109 102
103static const u32 atl1_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
104 NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
105
106static int debug = -1;
107module_param(debug, int, 0);
108MODULE_PARM_DESC(debug, "Message level (0=none,...,16=all)");
109
110/*
111 * Reset the transmit and receive units; mask and clear all interrupts.
112 * hw - Struct containing variables accessed by shared code
113 * return : 0 or idle status (if error)
114 */
115static s32 atl1_reset_hw(struct atl1_hw *hw)
116{
117 struct pci_dev *pdev = hw->back->pdev;
118 struct atl1_adapter *adapter = hw->back;
119 u32 icr;
120 int i;
121
122 /*
123 * Clear Interrupt mask to stop board from generating
124 * interrupts & Clear any pending interrupt events
125 */
126 /*
127 * iowrite32(0, hw->hw_addr + REG_IMR);
128 * iowrite32(0xffffffff, hw->hw_addr + REG_ISR);
129 */
130
131 /*
132 * Issue Soft Reset to the MAC. This will reset the chip's
133 * transmit, receive, DMA. It will not effect
134 * the current PCI configuration. The global reset bit is self-
135 * clearing, and should clear within a microsecond.
136 */
137 iowrite32(MASTER_CTRL_SOFT_RST, hw->hw_addr + REG_MASTER_CTRL);
138 ioread32(hw->hw_addr + REG_MASTER_CTRL);
139
140 iowrite16(1, hw->hw_addr + REG_PHY_ENABLE);
141 ioread16(hw->hw_addr + REG_PHY_ENABLE);
142
143 /* delay about 1ms */
144 msleep(1);
145
146 /* Wait at least 10ms for All module to be Idle */
147 for (i = 0; i < 10; i++) {
148 icr = ioread32(hw->hw_addr + REG_IDLE_STATUS);
149 if (!icr)
150 break;
151 /* delay 1 ms */
152 msleep(1);
153 /* FIXME: still the right way to do this? */
154 cpu_relax();
155 }
156
157 if (icr) {
158 if (netif_msg_hw(adapter))
159 dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
160 return icr;
161 }
162
163 return 0;
164}
165
166/* function about EEPROM
167 *
168 * check_eeprom_exist
169 * return 0 if eeprom exist
170 */
171static int atl1_check_eeprom_exist(struct atl1_hw *hw)
172{
173 u32 value;
174 value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
175 if (value & SPI_FLASH_CTRL_EN_VPD) {
176 value &= ~SPI_FLASH_CTRL_EN_VPD;
177 iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
178 }
179
180 value = ioread16(hw->hw_addr + REG_PCIE_CAP_LIST);
181 return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
182}
183
184static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value)
185{
186 int i;
187 u32 control;
188
189 if (offset & 3)
190 /* address do not align */
191 return false;
192
193 iowrite32(0, hw->hw_addr + REG_VPD_DATA);
194 control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
195 iowrite32(control, hw->hw_addr + REG_VPD_CAP);
196 ioread32(hw->hw_addr + REG_VPD_CAP);
197
198 for (i = 0; i < 10; i++) {
199 msleep(2);
200 control = ioread32(hw->hw_addr + REG_VPD_CAP);
201 if (control & VPD_CAP_VPD_FLAG)
202 break;
203 }
204 if (control & VPD_CAP_VPD_FLAG) {
205 *p_value = ioread32(hw->hw_addr + REG_VPD_DATA);
206 return true;
207 }
208 /* timeout */
209 return false;
210}
211
212/*
213 * Reads the value from a PHY register
214 * hw - Struct containing variables accessed by shared code
215 * reg_addr - address of the PHY register to read
216 */
217s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
218{
219 u32 val;
220 int i;
221
222 val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
223 MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
224 MDIO_CLK_SEL_SHIFT;
225 iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
226 ioread32(hw->hw_addr + REG_MDIO_CTRL);
227
228 for (i = 0; i < MDIO_WAIT_TIMES; i++) {
229 udelay(2);
230 val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
231 if (!(val & (MDIO_START | MDIO_BUSY)))
232 break;
233 }
234 if (!(val & (MDIO_START | MDIO_BUSY))) {
235 *phy_data = (u16) val;
236 return 0;
237 }
238 return ATLX_ERR_PHY;
239}
240
241#define CUSTOM_SPI_CS_SETUP 2
242#define CUSTOM_SPI_CLK_HI 2
243#define CUSTOM_SPI_CLK_LO 2
244#define CUSTOM_SPI_CS_HOLD 2
245#define CUSTOM_SPI_CS_HI 3
246
247static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
248{
249 int i;
250 u32 value;
251
252 iowrite32(0, hw->hw_addr + REG_SPI_DATA);
253 iowrite32(addr, hw->hw_addr + REG_SPI_ADDR);
254
255 value = SPI_FLASH_CTRL_WAIT_READY |
256 (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) <<
257 SPI_FLASH_CTRL_CS_SETUP_SHIFT | (CUSTOM_SPI_CLK_HI &
258 SPI_FLASH_CTRL_CLK_HI_MASK) <<
259 SPI_FLASH_CTRL_CLK_HI_SHIFT | (CUSTOM_SPI_CLK_LO &
260 SPI_FLASH_CTRL_CLK_LO_MASK) <<
261 SPI_FLASH_CTRL_CLK_LO_SHIFT | (CUSTOM_SPI_CS_HOLD &
262 SPI_FLASH_CTRL_CS_HOLD_MASK) <<
263 SPI_FLASH_CTRL_CS_HOLD_SHIFT | (CUSTOM_SPI_CS_HI &
264 SPI_FLASH_CTRL_CS_HI_MASK) <<
265 SPI_FLASH_CTRL_CS_HI_SHIFT | (1 & SPI_FLASH_CTRL_INS_MASK) <<
266 SPI_FLASH_CTRL_INS_SHIFT;
267
268 iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
269
270 value |= SPI_FLASH_CTRL_START;
271 iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
272 ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
273
274 for (i = 0; i < 10; i++) {
275 msleep(1);
276 value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
277 if (!(value & SPI_FLASH_CTRL_START))
278 break;
279 }
280
281 if (value & SPI_FLASH_CTRL_START)
282 return false;
283
284 *buf = ioread32(hw->hw_addr + REG_SPI_DATA);
285
286 return true;
287}
288
289/*
290 * get_permanent_address
291 * return 0 if get valid mac address,
292 */
293static int atl1_get_permanent_address(struct atl1_hw *hw)
294{
295 u32 addr[2];
296 u32 i, control;
297 u16 reg;
298 u8 eth_addr[ETH_ALEN];
299 bool key_valid;
300
301 if (is_valid_ether_addr(hw->perm_mac_addr))
302 return 0;
303
304 /* init */
305 addr[0] = addr[1] = 0;
306
307 if (!atl1_check_eeprom_exist(hw)) {
308 reg = 0;
309 key_valid = false;
310 /* Read out all EEPROM content */
311 i = 0;
312 while (1) {
313 if (atl1_read_eeprom(hw, i + 0x100, &control)) {
314 if (key_valid) {
315 if (reg == REG_MAC_STA_ADDR)
316 addr[0] = control;
317 else if (reg == (REG_MAC_STA_ADDR + 4))
318 addr[1] = control;
319 key_valid = false;
320 } else if ((control & 0xff) == 0x5A) {
321 key_valid = true;
322 reg = (u16) (control >> 16);
323 } else
324 break;
325 } else
326 /* read error */
327 break;
328 i += 4;
329 }
330
331 *(u32 *) &eth_addr[2] = swab32(addr[0]);
332 *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
333 if (is_valid_ether_addr(eth_addr)) {
334 memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
335 return 0;
336 }
337 return 1;
338 }
339
340 /* see if SPI FLAGS exist ? */
341 addr[0] = addr[1] = 0;
342 reg = 0;
343 key_valid = false;
344 i = 0;
345 while (1) {
346 if (atl1_spi_read(hw, i + 0x1f000, &control)) {
347 if (key_valid) {
348 if (reg == REG_MAC_STA_ADDR)
349 addr[0] = control;
350 else if (reg == (REG_MAC_STA_ADDR + 4))
351 addr[1] = control;
352 key_valid = false;
353 } else if ((control & 0xff) == 0x5A) {
354 key_valid = true;
355 reg = (u16) (control >> 16);
356 } else
357 /* data end */
358 break;
359 } else
360 /* read error */
361 break;
362 i += 4;
363 }
364
365 *(u32 *) &eth_addr[2] = swab32(addr[0]);
366 *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
367 if (is_valid_ether_addr(eth_addr)) {
368 memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
369 return 0;
370 }
371
372 /*
373 * On some motherboards, the MAC address is written by the
374 * BIOS directly to the MAC register during POST, and is
375 * not stored in eeprom. If all else thus far has failed
376 * to fetch the permanent MAC address, try reading it directly.
377 */
378 addr[0] = ioread32(hw->hw_addr + REG_MAC_STA_ADDR);
379 addr[1] = ioread16(hw->hw_addr + (REG_MAC_STA_ADDR + 4));
380 *(u32 *) &eth_addr[2] = swab32(addr[0]);
381 *(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
382 if (is_valid_ether_addr(eth_addr)) {
383 memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
384 return 0;
385 }
386
387 return 1;
388}
389
390/*
391 * Reads the adapter's MAC address from the EEPROM
392 * hw - Struct containing variables accessed by shared code
393 */
394s32 atl1_read_mac_addr(struct atl1_hw *hw)
395{
396 u16 i;
397
398 if (atl1_get_permanent_address(hw))
399 random_ether_addr(hw->perm_mac_addr);
400
401 for (i = 0; i < ETH_ALEN; i++)
402 hw->mac_addr[i] = hw->perm_mac_addr[i];
403 return 0;
404}
405
406/*
407 * Hashes an address to determine its location in the multicast table
408 * hw - Struct containing variables accessed by shared code
409 * mc_addr - the multicast address to hash
410 *
411 * atl1_hash_mc_addr
412 * purpose
413 * set hash value for a multicast address
414 * hash calcu processing :
415 * 1. calcu 32bit CRC for multicast address
416 * 2. reverse crc with MSB to LSB
417 */
418u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
419{
420 u32 crc32, value = 0;
421 int i;
422
423 crc32 = ether_crc_le(6, mc_addr);
424 for (i = 0; i < 32; i++)
425 value |= (((crc32 >> i) & 1) << (31 - i));
426
427 return value;
428}
429
430/*
431 * Sets the bit in the multicast table corresponding to the hash value.
432 * hw - Struct containing variables accessed by shared code
433 * hash_value - Multicast address hash value
434 */
435void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
436{
437 u32 hash_bit, hash_reg;
438 u32 mta;
439
440 /*
441 * The HASH Table is a register array of 2 32-bit registers.
442 * It is treated like an array of 64 bits. We want to set
443 * bit BitArray[hash_value]. So we figure out what register
444 * the bit is in, read it, OR in the new bit, then write
445 * back the new value. The register is determined by the
446 * upper 7 bits of the hash value and the bit within that
447 * register are determined by the lower 5 bits of the value.
448 */
449 hash_reg = (hash_value >> 31) & 0x1;
450 hash_bit = (hash_value >> 26) & 0x1F;
451 mta = ioread32((hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
452 mta |= (1 << hash_bit);
453 iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
454}
455
456/*
457 * Writes a value to a PHY register
458 * hw - Struct containing variables accessed by shared code
459 * reg_addr - address of the PHY register to write
460 * data - data to write to the PHY
461 */
462static s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data)
463{
464 int i;
465 u32 val;
466
467 val = ((u32) (phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
468 (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
469 MDIO_SUP_PREAMBLE |
470 MDIO_START | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
471 iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
472 ioread32(hw->hw_addr + REG_MDIO_CTRL);
473
474 for (i = 0; i < MDIO_WAIT_TIMES; i++) {
475 udelay(2);
476 val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
477 if (!(val & (MDIO_START | MDIO_BUSY)))
478 break;
479 }
480
481 if (!(val & (MDIO_START | MDIO_BUSY)))
482 return 0;
483
484 return ATLX_ERR_PHY;
485}
486
487/*
488 * Make L001's PHY out of Power Saving State (bug)
489 * hw - Struct containing variables accessed by shared code
490 * when power on, L001's PHY always on Power saving State
491 * (Gigabit Link forbidden)
492 */
493static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
494{
495 s32 ret;
496 ret = atl1_write_phy_reg(hw, 29, 0x0029);
497 if (ret)
498 return ret;
499 return atl1_write_phy_reg(hw, 30, 0);
500}
501
502/*
503 *TODO: do something or get rid of this
504 */
505#ifdef CONFIG_PM
506static s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
507{
508/* s32 ret_val;
509 * u16 phy_data;
510 */
511
512/*
513 ret_val = atl1_write_phy_reg(hw, ...);
514 ret_val = atl1_write_phy_reg(hw, ...);
515 ....
516*/
517 return 0;
518}
519#endif
520
521/*
522 * Resets the PHY and make all config validate
523 * hw - Struct containing variables accessed by shared code
524 *
525 * Sets bit 15 and 12 of the MII Control regiser (for F001 bug)
526 */
527static s32 atl1_phy_reset(struct atl1_hw *hw)
528{
529 struct pci_dev *pdev = hw->back->pdev;
530 struct atl1_adapter *adapter = hw->back;
531 s32 ret_val;
532 u16 phy_data;
533
534 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
535 hw->media_type == MEDIA_TYPE_1000M_FULL)
536 phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
537 else {
538 switch (hw->media_type) {
539 case MEDIA_TYPE_100M_FULL:
540 phy_data =
541 MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
542 MII_CR_RESET;
543 break;
544 case MEDIA_TYPE_100M_HALF:
545 phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
546 break;
547 case MEDIA_TYPE_10M_FULL:
548 phy_data =
549 MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
550 break;
551 default:
552 /* MEDIA_TYPE_10M_HALF: */
553 phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
554 break;
555 }
556 }
557
558 ret_val = atl1_write_phy_reg(hw, MII_BMCR, phy_data);
559 if (ret_val) {
560 u32 val;
561 int i;
562 /* pcie serdes link may be down! */
563 if (netif_msg_hw(adapter))
564 dev_dbg(&pdev->dev, "pcie phy link down\n");
565
566 for (i = 0; i < 25; i++) {
567 msleep(1);
568 val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
569 if (!(val & (MDIO_START | MDIO_BUSY)))
570 break;
571 }
572
573 if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
574 if (netif_msg_hw(adapter))
575 dev_warn(&pdev->dev,
576 "pcie link down at least 25ms\n");
577 return ret_val;
578 }
579 }
580 return 0;
581}
582
583/*
584 * Configures PHY autoneg and flow control advertisement settings
585 * hw - Struct containing variables accessed by shared code
586 */
587static s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
588{
589 s32 ret_val;
590 s16 mii_autoneg_adv_reg;
591 s16 mii_1000t_ctrl_reg;
592
593 /* Read the MII Auto-Neg Advertisement Register (Address 4). */
594 mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
595
596 /* Read the MII 1000Base-T Control Register (Address 9). */
597 mii_1000t_ctrl_reg = MII_ATLX_CR_1000T_DEFAULT_CAP_MASK;
598
599 /*
600 * First we clear all the 10/100 mb speed bits in the Auto-Neg
601 * Advertisement Register (Address 4) and the 1000 mb speed bits in
602 * the 1000Base-T Control Register (Address 9).
603 */
604 mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
605 mii_1000t_ctrl_reg &= ~MII_ATLX_CR_1000T_SPEED_MASK;
606
607 /*
608 * Need to parse media_type and set up
609 * the appropriate PHY registers.
610 */
611 switch (hw->media_type) {
612 case MEDIA_TYPE_AUTO_SENSOR:
613 mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS |
614 MII_AR_10T_FD_CAPS |
615 MII_AR_100TX_HD_CAPS |
616 MII_AR_100TX_FD_CAPS);
617 mii_1000t_ctrl_reg |= MII_ATLX_CR_1000T_FD_CAPS;
618 break;
619
620 case MEDIA_TYPE_1000M_FULL:
621 mii_1000t_ctrl_reg |= MII_ATLX_CR_1000T_FD_CAPS;
622 break;
623
624 case MEDIA_TYPE_100M_FULL:
625 mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
626 break;
627
628 case MEDIA_TYPE_100M_HALF:
629 mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
630 break;
631
632 case MEDIA_TYPE_10M_FULL:
633 mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
634 break;
635
636 default:
637 mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
638 break;
639 }
640
641 /* flow control fixed to enable all */
642 mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
643
644 hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
645 hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg;
646
647 ret_val = atl1_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
648 if (ret_val)
649 return ret_val;
650
651 ret_val = atl1_write_phy_reg(hw, MII_ATLX_CR, mii_1000t_ctrl_reg);
652 if (ret_val)
653 return ret_val;
654
655 return 0;
656}
657
658/*
659 * Configures link settings.
660 * hw - Struct containing variables accessed by shared code
661 * Assumes the hardware has previously been reset and the
662 * transmitter and receiver are not enabled.
663 */
664static s32 atl1_setup_link(struct atl1_hw *hw)
665{
666 struct pci_dev *pdev = hw->back->pdev;
667 struct atl1_adapter *adapter = hw->back;
668 s32 ret_val;
669
670 /*
671 * Options:
672 * PHY will advertise value(s) parsed from
673 * autoneg_advertised and fc
674 * no matter what autoneg is , We will not wait link result.
675 */
676 ret_val = atl1_phy_setup_autoneg_adv(hw);
677 if (ret_val) {
678 if (netif_msg_link(adapter))
679 dev_dbg(&pdev->dev,
680 "error setting up autonegotiation\n");
681 return ret_val;
682 }
683 /* SW.Reset , En-Auto-Neg if needed */
684 ret_val = atl1_phy_reset(hw);
685 if (ret_val) {
686 if (netif_msg_link(adapter))
687 dev_dbg(&pdev->dev, "error resetting phy\n");
688 return ret_val;
689 }
690 hw->phy_configured = true;
691 return ret_val;
692}
693
694static void atl1_init_flash_opcode(struct atl1_hw *hw)
695{
696 if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
697 /* Atmel */
698 hw->flash_vendor = 0;
699
700 /* Init OP table */
701 iowrite8(flash_table[hw->flash_vendor].cmd_program,
702 hw->hw_addr + REG_SPI_FLASH_OP_PROGRAM);
703 iowrite8(flash_table[hw->flash_vendor].cmd_sector_erase,
704 hw->hw_addr + REG_SPI_FLASH_OP_SC_ERASE);
705 iowrite8(flash_table[hw->flash_vendor].cmd_chip_erase,
706 hw->hw_addr + REG_SPI_FLASH_OP_CHIP_ERASE);
707 iowrite8(flash_table[hw->flash_vendor].cmd_rdid,
708 hw->hw_addr + REG_SPI_FLASH_OP_RDID);
709 iowrite8(flash_table[hw->flash_vendor].cmd_wren,
710 hw->hw_addr + REG_SPI_FLASH_OP_WREN);
711 iowrite8(flash_table[hw->flash_vendor].cmd_rdsr,
712 hw->hw_addr + REG_SPI_FLASH_OP_RDSR);
713 iowrite8(flash_table[hw->flash_vendor].cmd_wrsr,
714 hw->hw_addr + REG_SPI_FLASH_OP_WRSR);
715 iowrite8(flash_table[hw->flash_vendor].cmd_read,
716 hw->hw_addr + REG_SPI_FLASH_OP_READ);
717}
718
719/*
720 * Performs basic configuration of the adapter.
721 * hw - Struct containing variables accessed by shared code
722 * Assumes that the controller has previously been reset and is in a
723 * post-reset uninitialized state. Initializes multicast table,
724 * and Calls routines to setup link
725 * Leaves the transmit and receive units disabled and uninitialized.
726 */
727static s32 atl1_init_hw(struct atl1_hw *hw)
728{
729 u32 ret_val = 0;
730
731 /* Zero out the Multicast HASH table */
732 iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
733 /* clear the old settings from the multicast hash table */
734 iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
735
736 atl1_init_flash_opcode(hw);
737
738 if (!hw->phy_configured) {
739 /* enable GPHY LinkChange Interrrupt */
740 ret_val = atl1_write_phy_reg(hw, 18, 0xC00);
741 if (ret_val)
742 return ret_val;
743 /* make PHY out of power-saving state */
744 ret_val = atl1_phy_leave_power_saving(hw);
745 if (ret_val)
746 return ret_val;
747 /* Call a subroutine to configure the link */
748 ret_val = atl1_setup_link(hw);
749 }
750 return ret_val;
751}
752
753/*
754 * Detects the current speed and duplex settings of the hardware.
755 * hw - Struct containing variables accessed by shared code
756 * speed - Speed of the connection
757 * duplex - Duplex setting of the connection
758 */
759static s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
760{
761 struct pci_dev *pdev = hw->back->pdev;
762 struct atl1_adapter *adapter = hw->back;
763 s32 ret_val;
764 u16 phy_data;
765
766 /* ; --- Read PHY Specific Status Register (17) */
767 ret_val = atl1_read_phy_reg(hw, MII_ATLX_PSSR, &phy_data);
768 if (ret_val)
769 return ret_val;
770
771 if (!(phy_data & MII_ATLX_PSSR_SPD_DPLX_RESOLVED))
772 return ATLX_ERR_PHY_RES;
773
774 switch (phy_data & MII_ATLX_PSSR_SPEED) {
775 case MII_ATLX_PSSR_1000MBS:
776 *speed = SPEED_1000;
777 break;
778 case MII_ATLX_PSSR_100MBS:
779 *speed = SPEED_100;
780 break;
781 case MII_ATLX_PSSR_10MBS:
782 *speed = SPEED_10;
783 break;
784 default:
785 if (netif_msg_hw(adapter))
786 dev_dbg(&pdev->dev, "error getting speed\n");
787 return ATLX_ERR_PHY_SPEED;
788 break;
789 }
790 if (phy_data & MII_ATLX_PSSR_DPLX)
791 *duplex = FULL_DUPLEX;
792 else
793 *duplex = HALF_DUPLEX;
794
795 return 0;
796}
797
798void atl1_set_mac_addr(struct atl1_hw *hw)
799{
800 u32 value;
801 /*
802 * 00-0B-6A-F6-00-DC
803 * 0: 6AF600DC 1: 000B
804 * low dword
805 */
806 value = (((u32) hw->mac_addr[2]) << 24) |
807 (((u32) hw->mac_addr[3]) << 16) |
808 (((u32) hw->mac_addr[4]) << 8) | (((u32) hw->mac_addr[5]));
809 iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR);
810 /* high dword */
811 value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1]));
812 iowrite32(value, (hw->hw_addr + REG_MAC_STA_ADDR) + (1 << 2));
813}
814
110/* 815/*
111 * atl1_sw_init - Initialize general software structures (struct atl1_adapter) 816 * atl1_sw_init - Initialize general software structures (struct atl1_adapter)
112 * @adapter: board private structure to initialize 817 * @adapter: board private structure to initialize
@@ -125,7 +830,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
125 830
126 adapter->wol = 0; 831 adapter->wol = 0;
127 adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7; 832 adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
128 adapter->ict = 50000; /* 100ms */ 833 adapter->ict = 50000; /* 100ms */
129 adapter->link_speed = SPEED_0; /* hardware init */ 834 adapter->link_speed = SPEED_0; /* hardware init */
130 adapter->link_duplex = FULL_DUPLEX; 835 adapter->link_duplex = FULL_DUPLEX;
131 836
@@ -206,30 +911,12 @@ static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
206} 911}
207 912
208/* 913/*
209 * atl1_ioctl -
210 * @netdev:
211 * @ifreq:
212 * @cmd:
213 */
214static int atl1_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
215{
216 switch (cmd) {
217 case SIOCGMIIPHY:
218 case SIOCGMIIREG:
219 case SIOCSMIIREG:
220 return atl1_mii_ioctl(netdev, ifr, cmd);
221 default:
222 return -EOPNOTSUPP;
223 }
224}
225
226/*
227 * atl1_setup_mem_resources - allocate Tx / RX descriptor resources 914 * atl1_setup_mem_resources - allocate Tx / RX descriptor resources
228 * @adapter: board private structure 915 * @adapter: board private structure
229 * 916 *
230 * Return 0 on success, negative on failure 917 * Return 0 on success, negative on failure
231 */ 918 */
232s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) 919static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
233{ 920{
234 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; 921 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
235 struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; 922 struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
@@ -242,13 +929,16 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
242 size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count); 929 size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count);
243 tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL); 930 tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
244 if (unlikely(!tpd_ring->buffer_info)) { 931 if (unlikely(!tpd_ring->buffer_info)) {
245 dev_err(&pdev->dev, "kzalloc failed , size = D%d\n", size); 932 if (netif_msg_drv(adapter))
933 dev_err(&pdev->dev, "kzalloc failed , size = D%d\n",
934 size);
246 goto err_nomem; 935 goto err_nomem;
247 } 936 }
248 rfd_ring->buffer_info = 937 rfd_ring->buffer_info =
249 (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count); 938 (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
250 939
251 /* real ring DMA buffer 940 /*
941 * real ring DMA buffer
252 * each ring/block may need up to 8 bytes for alignment, hence the 942 * each ring/block may need up to 8 bytes for alignment, hence the
253 * additional 40 bytes tacked onto the end. 943 * additional 40 bytes tacked onto the end.
254 */ 944 */
@@ -263,7 +953,8 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
263 ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, 953 ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
264 &ring_header->dma); 954 &ring_header->dma);
265 if (unlikely(!ring_header->desc)) { 955 if (unlikely(!ring_header->desc)) {
266 dev_err(&pdev->dev, "pci_alloc_consistent failed\n"); 956 if (netif_msg_drv(adapter))
957 dev_err(&pdev->dev, "pci_alloc_consistent failed\n");
267 goto err_nomem; 958 goto err_nomem;
268 } 959 }
269 960
@@ -307,7 +998,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
307 ((u8 *) adapter->cmb.cmb + 998 ((u8 *) adapter->cmb.cmb +
308 (sizeof(struct coals_msg_block) + offset)); 999 (sizeof(struct coals_msg_block) + offset));
309 1000
310 return ATL1_SUCCESS; 1001 return 0;
311 1002
312err_nomem: 1003err_nomem:
313 kfree(tpd_ring->buffer_info); 1004 kfree(tpd_ring->buffer_info);
@@ -416,7 +1107,7 @@ static void atl1_clean_tx_ring(struct atl1_adapter *adapter)
416 * 1107 *
417 * Free all transmit software resources 1108 * Free all transmit software resources
418 */ 1109 */
419void atl1_free_ring_resources(struct atl1_adapter *adapter) 1110static void atl1_free_ring_resources(struct atl1_adapter *adapter)
420{ 1111{
421 struct pci_dev *pdev = adapter->pdev; 1112 struct pci_dev *pdev = adapter->pdev;
422 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; 1113 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
@@ -481,31 +1172,6 @@ static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
481 iowrite32(value, hw->hw_addr + REG_MAC_CTRL); 1172 iowrite32(value, hw->hw_addr + REG_MAC_CTRL);
482} 1173}
483 1174
484/*
485 * atl1_set_mac - Change the Ethernet Address of the NIC
486 * @netdev: network interface device structure
487 * @p: pointer to an address structure
488 *
489 * Returns 0 on success, negative on failure
490 */
491static int atl1_set_mac(struct net_device *netdev, void *p)
492{
493 struct atl1_adapter *adapter = netdev_priv(netdev);
494 struct sockaddr *addr = p;
495
496 if (netif_running(netdev))
497 return -EBUSY;
498
499 if (!is_valid_ether_addr(addr->sa_data))
500 return -EADDRNOTAVAIL;
501
502 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
503 memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
504
505 atl1_set_mac_addr(&adapter->hw);
506 return 0;
507}
508
509static u32 atl1_check_link(struct atl1_adapter *adapter) 1175static u32 atl1_check_link(struct atl1_adapter *adapter)
510{ 1176{
511 struct atl1_hw *hw = &adapter->hw; 1177 struct atl1_hw *hw = &adapter->hw;
@@ -517,14 +1183,17 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
517 /* MII_BMSR must read twice */ 1183 /* MII_BMSR must read twice */
518 atl1_read_phy_reg(hw, MII_BMSR, &phy_data); 1184 atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
519 atl1_read_phy_reg(hw, MII_BMSR, &phy_data); 1185 atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
520 if (!(phy_data & BMSR_LSTATUS)) { /* link down */ 1186 if (!(phy_data & BMSR_LSTATUS)) {
521 if (netif_carrier_ok(netdev)) { /* old link state: Up */ 1187 /* link down */
522 dev_info(&adapter->pdev->dev, "link is down\n"); 1188 if (netif_carrier_ok(netdev)) {
1189 /* old link state: Up */
1190 if (netif_msg_link(adapter))
1191 dev_info(&adapter->pdev->dev, "link is down\n");
523 adapter->link_speed = SPEED_0; 1192 adapter->link_speed = SPEED_0;
524 netif_carrier_off(netdev); 1193 netif_carrier_off(netdev);
525 netif_stop_queue(netdev); 1194 netif_stop_queue(netdev);
526 } 1195 }
527 return ATL1_SUCCESS; 1196 return 0;
528 } 1197 }
529 1198
530 /* Link Up */ 1199 /* Link Up */
@@ -562,20 +1231,22 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
562 adapter->link_speed = speed; 1231 adapter->link_speed = speed;
563 adapter->link_duplex = duplex; 1232 adapter->link_duplex = duplex;
564 atl1_setup_mac_ctrl(adapter); 1233 atl1_setup_mac_ctrl(adapter);
565 dev_info(&adapter->pdev->dev, 1234 if (netif_msg_link(adapter))
566 "%s link is up %d Mbps %s\n", 1235 dev_info(&adapter->pdev->dev,
567 netdev->name, adapter->link_speed, 1236 "%s link is up %d Mbps %s\n",
568 adapter->link_duplex == FULL_DUPLEX ? 1237 netdev->name, adapter->link_speed,
569 "full duplex" : "half duplex"); 1238 adapter->link_duplex == FULL_DUPLEX ?
1239 "full duplex" : "half duplex");
570 } 1240 }
571 if (!netif_carrier_ok(netdev)) { /* Link down -> Up */ 1241 if (!netif_carrier_ok(netdev)) {
1242 /* Link down -> Up */
572 netif_carrier_on(netdev); 1243 netif_carrier_on(netdev);
573 netif_wake_queue(netdev); 1244 netif_wake_queue(netdev);
574 } 1245 }
575 return ATL1_SUCCESS; 1246 return 0;
576 } 1247 }
577 1248
578 /* change orignal link status */ 1249 /* change original link status */
579 if (netif_carrier_ok(netdev)) { 1250 if (netif_carrier_ok(netdev)) {
580 adapter->link_speed = SPEED_0; 1251 adapter->link_speed = SPEED_0;
581 netif_carrier_off(netdev); 1252 netif_carrier_off(netdev);
@@ -596,12 +1267,13 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
596 phy_data = 1267 phy_data =
597 MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET; 1268 MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
598 break; 1269 break;
599 default: /* MEDIA_TYPE_10M_HALF: */ 1270 default:
1271 /* MEDIA_TYPE_10M_HALF: */
600 phy_data = MII_CR_SPEED_10 | MII_CR_RESET; 1272 phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
601 break; 1273 break;
602 } 1274 }
603 atl1_write_phy_reg(hw, MII_BMCR, phy_data); 1275 atl1_write_phy_reg(hw, MII_BMCR, phy_data);
604 return ATL1_SUCCESS; 1276 return 0;
605 } 1277 }
606 1278
607 /* auto-neg, insert timer to re-config phy */ 1279 /* auto-neg, insert timer to re-config phy */
@@ -610,103 +1282,6 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
610 mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ); 1282 mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ);
611 } 1283 }
612 1284
613 return ATL1_SUCCESS;
614}
615
616static void atl1_check_for_link(struct atl1_adapter *adapter)
617{
618 struct net_device *netdev = adapter->netdev;
619 u16 phy_data = 0;
620
621 spin_lock(&adapter->lock);
622 adapter->phy_timer_pending = false;
623 atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
624 atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
625 spin_unlock(&adapter->lock);
626
627 /* notify upper layer link down ASAP */
628 if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */
629 if (netif_carrier_ok(netdev)) { /* old link state: Up */
630 dev_info(&adapter->pdev->dev, "%s link is down\n",
631 netdev->name);
632 adapter->link_speed = SPEED_0;
633 netif_carrier_off(netdev);
634 netif_stop_queue(netdev);
635 }
636 }
637 schedule_work(&adapter->link_chg_task);
638}
639
640/*
641 * atl1_set_multi - Multicast and Promiscuous mode set
642 * @netdev: network interface device structure
643 *
644 * The set_multi entry point is called whenever the multicast address
645 * list or the network interface flags are updated. This routine is
646 * responsible for configuring the hardware for proper multicast,
647 * promiscuous mode, and all-multi behavior.
648 */
649static void atl1_set_multi(struct net_device *netdev)
650{
651 struct atl1_adapter *adapter = netdev_priv(netdev);
652 struct atl1_hw *hw = &adapter->hw;
653 struct dev_mc_list *mc_ptr;
654 u32 rctl;
655 u32 hash_value;
656
657 /* Check for Promiscuous and All Multicast modes */
658 rctl = ioread32(hw->hw_addr + REG_MAC_CTRL);
659 if (netdev->flags & IFF_PROMISC)
660 rctl |= MAC_CTRL_PROMIS_EN;
661 else if (netdev->flags & IFF_ALLMULTI) {
662 rctl |= MAC_CTRL_MC_ALL_EN;
663 rctl &= ~MAC_CTRL_PROMIS_EN;
664 } else
665 rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
666
667 iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL);
668
669 /* clear the old settings from the multicast hash table */
670 iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
671 iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
672
673 /* compute mc addresses' hash value ,and put it into hash table */
674 for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
675 hash_value = atl1_hash_mc_addr(hw, mc_ptr->dmi_addr);
676 atl1_hash_set(hw, hash_value);
677 }
678}
679
680/*
681 * atl1_change_mtu - Change the Maximum Transfer Unit
682 * @netdev: network interface device structure
683 * @new_mtu: new value for maximum frame size
684 *
685 * Returns 0 on success, negative on failure
686 */
687static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
688{
689 struct atl1_adapter *adapter = netdev_priv(netdev);
690 int old_mtu = netdev->mtu;
691 int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
692
693 if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
694 (max_frame > MAX_JUMBO_FRAME_SIZE)) {
695 dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
696 return -EINVAL;
697 }
698
699 adapter->hw.max_frame_size = max_frame;
700 adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3;
701 adapter->rx_buffer_len = (max_frame + 7) & ~7;
702 adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8;
703
704 netdev->mtu = new_mtu;
705 if ((old_mtu != new_mtu) && netif_running(netdev)) {
706 atl1_down(adapter);
707 atl1_up(adapter);
708 }
709
710 return 0; 1285 return 0;
711} 1286}
712 1287
@@ -974,37 +1549,6 @@ static void atl1_via_workaround(struct atl1_adapter *adapter)
974 iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND); 1549 iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
975} 1550}
976 1551
977/*
978 * atl1_irq_enable - Enable default interrupt generation settings
979 * @adapter: board private structure
980 */
981static void atl1_irq_enable(struct atl1_adapter *adapter)
982{
983 iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
984 ioread32(adapter->hw.hw_addr + REG_IMR);
985}
986
987/*
988 * atl1_irq_disable - Mask off interrupt generation on the NIC
989 * @adapter: board private structure
990 */
991static void atl1_irq_disable(struct atl1_adapter *adapter)
992{
993 iowrite32(0, adapter->hw.hw_addr + REG_IMR);
994 ioread32(adapter->hw.hw_addr + REG_IMR);
995 synchronize_irq(adapter->pdev->irq);
996}
997
998static void atl1_clear_phy_int(struct atl1_adapter *adapter)
999{
1000 u16 phy_data;
1001 unsigned long flags;
1002
1003 spin_lock_irqsave(&adapter->lock, flags);
1004 atl1_read_phy_reg(&adapter->hw, 19, &phy_data);
1005 spin_unlock_irqrestore(&adapter->lock, flags);
1006}
1007
1008static void atl1_inc_smb(struct atl1_adapter *adapter) 1552static void atl1_inc_smb(struct atl1_adapter *adapter)
1009{ 1553{
1010 struct stats_msg_block *smb = adapter->smb.smb; 1554 struct stats_msg_block *smb = adapter->smb.smb;
@@ -1076,19 +1620,6 @@ static void atl1_inc_smb(struct atl1_adapter *adapter)
1076 adapter->soft_stats.tx_carrier_errors; 1620 adapter->soft_stats.tx_carrier_errors;
1077} 1621}
1078 1622
1079/*
1080 * atl1_get_stats - Get System Network Statistics
1081 * @netdev: network interface device structure
1082 *
1083 * Returns the address of the device statistics structure.
1084 * The statistics are actually updated from the timer callback.
1085 */
1086static struct net_device_stats *atl1_get_stats(struct net_device *netdev)
1087{
1088 struct atl1_adapter *adapter = netdev_priv(netdev);
1089 return &adapter->net_stats;
1090}
1091
1092static void atl1_update_mailbox(struct atl1_adapter *adapter) 1623static void atl1_update_mailbox(struct atl1_adapter *adapter)
1093{ 1624{
1094 unsigned long flags; 1625 unsigned long flags;
@@ -1150,8 +1681,9 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
1150 if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | 1681 if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
1151 ERR_FLAG_CODE | ERR_FLAG_OV)) { 1682 ERR_FLAG_CODE | ERR_FLAG_OV)) {
1152 adapter->hw_csum_err++; 1683 adapter->hw_csum_err++;
1153 dev_printk(KERN_DEBUG, &pdev->dev, 1684 if (netif_msg_rx_err(adapter))
1154 "rx checksum error\n"); 1685 dev_printk(KERN_DEBUG, &pdev->dev,
1686 "rx checksum error\n");
1155 return; 1687 return;
1156 } 1688 }
1157 } 1689 }
@@ -1170,9 +1702,10 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
1170 } 1702 }
1171 1703
1172 /* IPv4, but hardware thinks its checksum is wrong */ 1704 /* IPv4, but hardware thinks its checksum is wrong */
1173 dev_printk(KERN_DEBUG, &pdev->dev, 1705 if (netif_msg_rx_err(adapter))
1174 "hw csum wrong, pkt_flag:%x, err_flag:%x\n", 1706 dev_printk(KERN_DEBUG, &pdev->dev,
1175 rrd->pkt_flg, rrd->err_flg); 1707 "hw csum wrong, pkt_flag:%x, err_flag:%x\n",
1708 rrd->pkt_flg, rrd->err_flg);
1176 skb->ip_summed = CHECKSUM_COMPLETE; 1709 skb->ip_summed = CHECKSUM_COMPLETE;
1177 skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum); 1710 skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
1178 adapter->hw_csum_err++; 1711 adapter->hw_csum_err++;
@@ -1210,7 +1743,8 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
1210 rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use); 1743 rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
1211 1744
1212 skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN); 1745 skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
1213 if (unlikely(!skb)) { /* Better luck next round */ 1746 if (unlikely(!skb)) {
1747 /* Better luck next round */
1214 adapter->net_stats.rx_dropped++; 1748 adapter->net_stats.rx_dropped++;
1215 break; 1749 break;
1216 } 1750 }
@@ -1281,18 +1815,39 @@ chk_rrd:
1281 /* check rrd status */ 1815 /* check rrd status */
1282 if (likely(rrd->num_buf == 1)) 1816 if (likely(rrd->num_buf == 1))
1283 goto rrd_ok; 1817 goto rrd_ok;
1818 else if (netif_msg_rx_err(adapter)) {
1819 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1820 "unexpected RRD buffer count\n");
1821 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1822 "rx_buf_len = %d\n",
1823 adapter->rx_buffer_len);
1824 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1825 "RRD num_buf = %d\n",
1826 rrd->num_buf);
1827 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1828 "RRD pkt_len = %d\n",
1829 rrd->xsz.xsum_sz.pkt_size);
1830 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1831 "RRD pkt_flg = 0x%08X\n",
1832 rrd->pkt_flg);
1833 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1834 "RRD err_flg = 0x%08X\n",
1835 rrd->err_flg);
1836 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1837 "RRD vlan_tag = 0x%08X\n",
1838 rrd->vlan_tag);
1839 }
1284 1840
1285 /* rrd seems to be bad */ 1841 /* rrd seems to be bad */
1286 if (unlikely(i-- > 0)) { 1842 if (unlikely(i-- > 0)) {
1287 /* rrd may not be DMAed completely */ 1843 /* rrd may not be DMAed completely */
1288 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1289 "incomplete RRD DMA transfer\n");
1290 udelay(1); 1844 udelay(1);
1291 goto chk_rrd; 1845 goto chk_rrd;
1292 } 1846 }
1293 /* bad rrd */ 1847 /* bad rrd */
1294 dev_printk(KERN_DEBUG, &adapter->pdev->dev, 1848 if (netif_msg_rx_err(adapter))
1295 "bad RRD\n"); 1849 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1850 "bad RRD\n");
1296 /* see if update RFD index */ 1851 /* see if update RFD index */
1297 if (rrd->num_buf > 1) 1852 if (rrd->num_buf > 1)
1298 atl1_update_rfd_index(adapter, rrd); 1853 atl1_update_rfd_index(adapter, rrd);
@@ -1411,8 +1966,6 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
1411 dev_kfree_skb_irq(buffer_info->skb); 1966 dev_kfree_skb_irq(buffer_info->skb);
1412 buffer_info->skb = NULL; 1967 buffer_info->skb = NULL;
1413 } 1968 }
1414 tpd->buffer_addr = 0;
1415 tpd->desc.data = 0;
1416 1969
1417 if (++sw_tpd_next_to_clean == tpd_ring->count) 1970 if (++sw_tpd_next_to_clean == tpd_ring->count)
1418 sw_tpd_next_to_clean = 0; 1971 sw_tpd_next_to_clean = 0;
@@ -1434,167 +1987,192 @@ static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
1434} 1987}
1435 1988
1436static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, 1989static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
1437 struct tso_param *tso) 1990 struct tx_packet_desc *ptpd)
1438{ 1991{
1439 /* We enter this function holding a spinlock. */ 1992 /* spinlock held */
1440 u8 ipofst; 1993 u8 hdr_len, ip_off;
1994 u32 real_len;
1441 int err; 1995 int err;
1442 1996
1443 if (skb_shinfo(skb)->gso_size) { 1997 if (skb_shinfo(skb)->gso_size) {
1444 if (skb_header_cloned(skb)) { 1998 if (skb_header_cloned(skb)) {
1445 err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); 1999 err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
1446 if (unlikely(err)) 2000 if (unlikely(err))
1447 return err; 2001 return -1;
1448 } 2002 }
1449 2003
1450 if (skb->protocol == ntohs(ETH_P_IP)) { 2004 if (skb->protocol == ntohs(ETH_P_IP)) {
1451 struct iphdr *iph = ip_hdr(skb); 2005 struct iphdr *iph = ip_hdr(skb);
1452 2006
1453 iph->tot_len = 0; 2007 real_len = (((unsigned char *)iph - skb->data) +
2008 ntohs(iph->tot_len));
2009 if (real_len < skb->len)
2010 pskb_trim(skb, real_len);
2011 hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
2012 if (skb->len == hdr_len) {
2013 iph->check = 0;
2014 tcp_hdr(skb)->check =
2015 ~csum_tcpudp_magic(iph->saddr,
2016 iph->daddr, tcp_hdrlen(skb),
2017 IPPROTO_TCP, 0);
2018 ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
2019 TPD_IPHL_SHIFT;
2020 ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
2021 TPD_TCPHDRLEN_MASK) <<
2022 TPD_TCPHDRLEN_SHIFT;
2023 ptpd->word3 |= 1 << TPD_IP_CSUM_SHIFT;
2024 ptpd->word3 |= 1 << TPD_TCP_CSUM_SHIFT;
2025 return 1;
2026 }
2027
1454 iph->check = 0; 2028 iph->check = 0;
1455 tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, 2029 tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
1456 iph->daddr, 0, IPPROTO_TCP, 0); 2030 iph->daddr, 0, IPPROTO_TCP, 0);
1457 ipofst = skb_network_offset(skb); 2031 ip_off = (unsigned char *)iph -
1458 if (ipofst != ETH_HLEN) /* 802.3 frame */ 2032 (unsigned char *) skb_network_header(skb);
1459 tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT; 2033 if (ip_off == 8) /* 802.3-SNAP frame */
1460 2034 ptpd->word3 |= 1 << TPD_ETHTYPE_SHIFT;
1461 tso->tsopl |= (iph->ihl & 2035 else if (ip_off != 0)
1462 CSUM_PARAM_IPHL_MASK) << CSUM_PARAM_IPHL_SHIFT; 2036 return -2;
1463 tso->tsopl |= (tcp_hdrlen(skb) & 2037
1464 TSO_PARAM_TCPHDRLEN_MASK) << 2038 ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
1465 TSO_PARAM_TCPHDRLEN_SHIFT; 2039 TPD_IPHL_SHIFT;
1466 tso->tsopl |= (skb_shinfo(skb)->gso_size & 2040 ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
1467 TSO_PARAM_MSS_MASK) << TSO_PARAM_MSS_SHIFT; 2041 TPD_TCPHDRLEN_MASK) << TPD_TCPHDRLEN_SHIFT;
1468 tso->tsopl |= 1 << TSO_PARAM_IPCKSUM_SHIFT; 2042 ptpd->word3 |= (skb_shinfo(skb)->gso_size &
1469 tso->tsopl |= 1 << TSO_PARAM_TCPCKSUM_SHIFT; 2043 TPD_MSS_MASK) << TPD_MSS_SHIFT;
1470 tso->tsopl |= 1 << TSO_PARAM_SEGMENT_SHIFT; 2044 ptpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
1471 return true; 2045 return 3;
1472 } 2046 }
1473 } 2047 }
1474 return false; 2048 return false;
1475} 2049}
1476 2050
1477static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, 2051static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
1478 struct csum_param *csum) 2052 struct tx_packet_desc *ptpd)
1479{ 2053{
1480 u8 css, cso; 2054 u8 css, cso;
1481 2055
1482 if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { 2056 if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
1483 cso = skb_transport_offset(skb); 2057 css = (u8) (skb->csum_start - skb_headroom(skb));
1484 css = cso + skb->csum_offset; 2058 cso = css + (u8) skb->csum_offset;
1485 if (unlikely(cso & 0x1)) { 2059 if (unlikely(css & 0x1)) {
1486 dev_printk(KERN_DEBUG, &adapter->pdev->dev, 2060 /* L1 hardware requires an even number here */
1487 "payload offset not an even number\n"); 2061 if (netif_msg_tx_err(adapter))
2062 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
2063 "payload offset not an even number\n");
1488 return -1; 2064 return -1;
1489 } 2065 }
1490 csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) << 2066 ptpd->word3 |= (css & TPD_PLOADOFFSET_MASK) <<
1491 CSUM_PARAM_PLOADOFFSET_SHIFT; 2067 TPD_PLOADOFFSET_SHIFT;
1492 csum->csumpl |= (css & CSUM_PARAM_XSUMOFFSET_MASK) << 2068 ptpd->word3 |= (cso & TPD_CCSUMOFFSET_MASK) <<
1493 CSUM_PARAM_XSUMOFFSET_SHIFT; 2069 TPD_CCSUMOFFSET_SHIFT;
1494 csum->csumpl |= 1 << CSUM_PARAM_CUSTOMCKSUM_SHIFT; 2070 ptpd->word3 |= 1 << TPD_CUST_CSUM_EN_SHIFT;
1495 return true; 2071 return true;
1496 } 2072 }
1497 2073 return 0;
1498 return true;
1499} 2074}
1500 2075
1501static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, 2076static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
1502 bool tcp_seg) 2077 struct tx_packet_desc *ptpd)
1503{ 2078{
1504 /* We enter this function holding a spinlock. */ 2079 /* spinlock held */
1505 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; 2080 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
1506 struct atl1_buffer *buffer_info; 2081 struct atl1_buffer *buffer_info;
2082 u16 buf_len = skb->len;
1507 struct page *page; 2083 struct page *page;
1508 int first_buf_len = skb->len;
1509 unsigned long offset; 2084 unsigned long offset;
1510 unsigned int nr_frags; 2085 unsigned int nr_frags;
1511 unsigned int f; 2086 unsigned int f;
1512 u16 tpd_next_to_use; 2087 int retval;
1513 u16 proto_hdr_len; 2088 u16 next_to_use;
1514 u16 len12; 2089 u16 data_len;
2090 u8 hdr_len;
1515 2091
1516 first_buf_len -= skb->data_len; 2092 buf_len -= skb->data_len;
1517 nr_frags = skb_shinfo(skb)->nr_frags; 2093 nr_frags = skb_shinfo(skb)->nr_frags;
1518 tpd_next_to_use = atomic_read(&tpd_ring->next_to_use); 2094 next_to_use = atomic_read(&tpd_ring->next_to_use);
1519 buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; 2095 buffer_info = &tpd_ring->buffer_info[next_to_use];
1520 if (unlikely(buffer_info->skb)) 2096 if (unlikely(buffer_info->skb))
1521 BUG(); 2097 BUG();
1522 buffer_info->skb = NULL; /* put skb in last TPD */ 2098 /* put skb in last TPD */
1523 2099 buffer_info->skb = NULL;
1524 if (tcp_seg) { 2100
1525 /* TSO/GSO */ 2101 retval = (ptpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
1526 proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); 2102 if (retval) {
1527 buffer_info->length = proto_hdr_len; 2103 /* TSO */
2104 hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
2105 buffer_info->length = hdr_len;
1528 page = virt_to_page(skb->data); 2106 page = virt_to_page(skb->data);
1529 offset = (unsigned long)skb->data & ~PAGE_MASK; 2107 offset = (unsigned long)skb->data & ~PAGE_MASK;
1530 buffer_info->dma = pci_map_page(adapter->pdev, page, 2108 buffer_info->dma = pci_map_page(adapter->pdev, page,
1531 offset, proto_hdr_len, 2109 offset, hdr_len,
1532 PCI_DMA_TODEVICE); 2110 PCI_DMA_TODEVICE);
1533 2111
1534 if (++tpd_next_to_use == tpd_ring->count) 2112 if (++next_to_use == tpd_ring->count)
1535 tpd_next_to_use = 0; 2113 next_to_use = 0;
1536 2114
1537 if (first_buf_len > proto_hdr_len) { 2115 if (buf_len > hdr_len) {
1538 int i, m; 2116 int i, nseg;
1539 2117
1540 len12 = first_buf_len - proto_hdr_len; 2118 data_len = buf_len - hdr_len;
1541 m = (len12 + ATL1_MAX_TX_BUF_LEN - 1) / 2119 nseg = (data_len + ATL1_MAX_TX_BUF_LEN - 1) /
1542 ATL1_MAX_TX_BUF_LEN; 2120 ATL1_MAX_TX_BUF_LEN;
1543 for (i = 0; i < m; i++) { 2121 for (i = 0; i < nseg; i++) {
1544 buffer_info = 2122 buffer_info =
1545 &tpd_ring->buffer_info[tpd_next_to_use]; 2123 &tpd_ring->buffer_info[next_to_use];
1546 buffer_info->skb = NULL; 2124 buffer_info->skb = NULL;
1547 buffer_info->length = 2125 buffer_info->length =
1548 (ATL1_MAX_TX_BUF_LEN >= 2126 (ATL1_MAX_TX_BUF_LEN >=
1549 len12) ? ATL1_MAX_TX_BUF_LEN : len12; 2127 data_len) ? ATL1_MAX_TX_BUF_LEN : data_len;
1550 len12 -= buffer_info->length; 2128 data_len -= buffer_info->length;
1551 page = virt_to_page(skb->data + 2129 page = virt_to_page(skb->data +
1552 (proto_hdr_len + 2130 (hdr_len + i * ATL1_MAX_TX_BUF_LEN));
1553 i * ATL1_MAX_TX_BUF_LEN));
1554 offset = (unsigned long)(skb->data + 2131 offset = (unsigned long)(skb->data +
1555 (proto_hdr_len + 2132 (hdr_len + i * ATL1_MAX_TX_BUF_LEN)) &
1556 i * ATL1_MAX_TX_BUF_LEN)) & ~PAGE_MASK; 2133 ~PAGE_MASK;
1557 buffer_info->dma = pci_map_page(adapter->pdev, 2134 buffer_info->dma = pci_map_page(adapter->pdev,
1558 page, offset, buffer_info->length, 2135 page, offset, buffer_info->length,
1559 PCI_DMA_TODEVICE); 2136 PCI_DMA_TODEVICE);
1560 if (++tpd_next_to_use == tpd_ring->count) 2137 if (++next_to_use == tpd_ring->count)
1561 tpd_next_to_use = 0; 2138 next_to_use = 0;
1562 } 2139 }
1563 } 2140 }
1564 } else { 2141 } else {
1565 /* not TSO/GSO */ 2142 /* not TSO */
1566 buffer_info->length = first_buf_len; 2143 buffer_info->length = buf_len;
1567 page = virt_to_page(skb->data); 2144 page = virt_to_page(skb->data);
1568 offset = (unsigned long)skb->data & ~PAGE_MASK; 2145 offset = (unsigned long)skb->data & ~PAGE_MASK;
1569 buffer_info->dma = pci_map_page(adapter->pdev, page, 2146 buffer_info->dma = pci_map_page(adapter->pdev, page,
1570 offset, first_buf_len, PCI_DMA_TODEVICE); 2147 offset, buf_len, PCI_DMA_TODEVICE);
1571 if (++tpd_next_to_use == tpd_ring->count) 2148 if (++next_to_use == tpd_ring->count)
1572 tpd_next_to_use = 0; 2149 next_to_use = 0;
1573 } 2150 }
1574 2151
1575 for (f = 0; f < nr_frags; f++) { 2152 for (f = 0; f < nr_frags; f++) {
1576 struct skb_frag_struct *frag; 2153 struct skb_frag_struct *frag;
1577 u16 lenf, i, m; 2154 u16 i, nseg;
1578 2155
1579 frag = &skb_shinfo(skb)->frags[f]; 2156 frag = &skb_shinfo(skb)->frags[f];
1580 lenf = frag->size; 2157 buf_len = frag->size;
1581 2158
1582 m = (lenf + ATL1_MAX_TX_BUF_LEN - 1) / ATL1_MAX_TX_BUF_LEN; 2159 nseg = (buf_len + ATL1_MAX_TX_BUF_LEN - 1) /
1583 for (i = 0; i < m; i++) { 2160 ATL1_MAX_TX_BUF_LEN;
1584 buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; 2161 for (i = 0; i < nseg; i++) {
2162 buffer_info = &tpd_ring->buffer_info[next_to_use];
1585 if (unlikely(buffer_info->skb)) 2163 if (unlikely(buffer_info->skb))
1586 BUG(); 2164 BUG();
1587 buffer_info->skb = NULL; 2165 buffer_info->skb = NULL;
1588 buffer_info->length = (lenf > ATL1_MAX_TX_BUF_LEN) ? 2166 buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
1589 ATL1_MAX_TX_BUF_LEN : lenf; 2167 ATL1_MAX_TX_BUF_LEN : buf_len;
1590 lenf -= buffer_info->length; 2168 buf_len -= buffer_info->length;
1591 buffer_info->dma = pci_map_page(adapter->pdev, 2169 buffer_info->dma = pci_map_page(adapter->pdev,
1592 frag->page, 2170 frag->page,
1593 frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN), 2171 frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN),
1594 buffer_info->length, PCI_DMA_TODEVICE); 2172 buffer_info->length, PCI_DMA_TODEVICE);
1595 2173
1596 if (++tpd_next_to_use == tpd_ring->count) 2174 if (++next_to_use == tpd_ring->count)
1597 tpd_next_to_use = 0; 2175 next_to_use = 0;
1598 } 2176 }
1599 } 2177 }
1600 2178
@@ -1602,39 +2180,44 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
1602 buffer_info->skb = skb; 2180 buffer_info->skb = skb;
1603} 2181}
1604 2182
1605static void atl1_tx_queue(struct atl1_adapter *adapter, int count, 2183static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
1606 union tpd_descr *descr) 2184 struct tx_packet_desc *ptpd)
1607{ 2185{
1608 /* We enter this function holding a spinlock. */ 2186 /* spinlock held */
1609 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; 2187 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
1610 int j;
1611 u32 val;
1612 struct atl1_buffer *buffer_info; 2188 struct atl1_buffer *buffer_info;
1613 struct tx_packet_desc *tpd; 2189 struct tx_packet_desc *tpd;
1614 u16 tpd_next_to_use = atomic_read(&tpd_ring->next_to_use); 2190 u16 j;
2191 u32 val;
2192 u16 next_to_use = (u16) atomic_read(&tpd_ring->next_to_use);
1615 2193
1616 for (j = 0; j < count; j++) { 2194 for (j = 0; j < count; j++) {
1617 buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; 2195 buffer_info = &tpd_ring->buffer_info[next_to_use];
1618 tpd = ATL1_TPD_DESC(&adapter->tpd_ring, tpd_next_to_use); 2196 tpd = ATL1_TPD_DESC(&adapter->tpd_ring, next_to_use);
1619 tpd->desc.csum.csumpu = descr->csum.csumpu; 2197 if (tpd != ptpd)
1620 tpd->desc.csum.csumpl = descr->csum.csumpl; 2198 memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
1621 tpd->desc.tso.tsopu = descr->tso.tsopu;
1622 tpd->desc.tso.tsopl = descr->tso.tsopl;
1623 tpd->buffer_addr = cpu_to_le64(buffer_info->dma); 2199 tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
1624 tpd->desc.data = descr->data; 2200 tpd->word2 = (cpu_to_le16(buffer_info->length) &
1625 tpd->desc.csum.csumpu |= (cpu_to_le16(buffer_info->length) & 2201 TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
1626 CSUM_PARAM_BUFLEN_MASK) << CSUM_PARAM_BUFLEN_SHIFT;
1627 2202
1628 val = (descr->tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) & 2203 /*
1629 TSO_PARAM_SEGMENT_MASK; 2204 * if this is the first packet in a TSO chain, set
1630 if (val && !j) 2205 * TPD_HDRFLAG, otherwise, clear it.
1631 tpd->desc.tso.tsopl |= 1 << TSO_PARAM_HDRFLAG_SHIFT; 2206 */
2207 val = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) &
2208 TPD_SEGMENT_EN_MASK;
2209 if (val) {
2210 if (!j)
2211 tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
2212 else
2213 tpd->word3 &= ~(1 << TPD_HDRFLAG_SHIFT);
2214 }
1632 2215
1633 if (j == (count - 1)) 2216 if (j == (count - 1))
1634 tpd->desc.csum.csumpl |= 1 << CSUM_PARAM_EOP_SHIFT; 2217 tpd->word3 |= 1 << TPD_EOP_SHIFT;
1635 2218
1636 if (++tpd_next_to_use == tpd_ring->count) 2219 if (++next_to_use == tpd_ring->count)
1637 tpd_next_to_use = 0; 2220 next_to_use = 0;
1638 } 2221 }
1639 /* 2222 /*
1640 * Force memory writes to complete before letting h/w 2223 * Force memory writes to complete before letting h/w
@@ -1644,18 +2227,18 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
1644 */ 2227 */
1645 wmb(); 2228 wmb();
1646 2229
1647 atomic_set(&tpd_ring->next_to_use, (int)tpd_next_to_use); 2230 atomic_set(&tpd_ring->next_to_use, next_to_use);
1648} 2231}
1649 2232
1650static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) 2233static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1651{ 2234{
1652 struct atl1_adapter *adapter = netdev_priv(netdev); 2235 struct atl1_adapter *adapter = netdev_priv(netdev);
2236 struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
1653 int len = skb->len; 2237 int len = skb->len;
1654 int tso; 2238 int tso;
1655 int count = 1; 2239 int count = 1;
1656 int ret_val; 2240 int ret_val;
1657 u32 val; 2241 struct tx_packet_desc *ptpd;
1658 union tpd_descr param;
1659 u16 frag_size; 2242 u16 frag_size;
1660 u16 vlan_tag; 2243 u16 vlan_tag;
1661 unsigned long flags; 2244 unsigned long flags;
@@ -1666,18 +2249,11 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1666 2249
1667 len -= skb->data_len; 2250 len -= skb->data_len;
1668 2251
1669 if (unlikely(skb->len == 0)) { 2252 if (unlikely(skb->len <= 0)) {
1670 dev_kfree_skb_any(skb); 2253 dev_kfree_skb_any(skb);
1671 return NETDEV_TX_OK; 2254 return NETDEV_TX_OK;
1672 } 2255 }
1673 2256
1674 param.data = 0;
1675 param.tso.tsopu = 0;
1676 param.tso.tsopl = 0;
1677 param.csum.csumpu = 0;
1678 param.csum.csumpl = 0;
1679
1680 /* nr_frags will be nonzero if we're doing scatter/gather (SG) */
1681 nr_frags = skb_shinfo(skb)->nr_frags; 2257 nr_frags = skb_shinfo(skb)->nr_frags;
1682 for (f = 0; f < nr_frags; f++) { 2258 for (f = 0; f < nr_frags; f++) {
1683 frag_size = skb_shinfo(skb)->frags[f].size; 2259 frag_size = skb_shinfo(skb)->frags[f].size;
@@ -1686,10 +2262,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1686 ATL1_MAX_TX_BUF_LEN; 2262 ATL1_MAX_TX_BUF_LEN;
1687 } 2263 }
1688 2264
1689 /* mss will be nonzero if we're doing segment offload (TSO/GSO) */
1690 mss = skb_shinfo(skb)->gso_size; 2265 mss = skb_shinfo(skb)->gso_size;
1691 if (mss) { 2266 if (mss) {
1692 if (skb->protocol == htons(ETH_P_IP)) { 2267 if (skb->protocol == ntohs(ETH_P_IP)) {
1693 proto_hdr_len = (skb_transport_offset(skb) + 2268 proto_hdr_len = (skb_transport_offset(skb) +
1694 tcp_hdrlen(skb)); 2269 tcp_hdrlen(skb));
1695 if (unlikely(proto_hdr_len > len)) { 2270 if (unlikely(proto_hdr_len > len)) {
@@ -1706,7 +2281,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1706 2281
1707 if (!spin_trylock_irqsave(&adapter->lock, flags)) { 2282 if (!spin_trylock_irqsave(&adapter->lock, flags)) {
1708 /* Can't get lock - tell upper layer to requeue */ 2283 /* Can't get lock - tell upper layer to requeue */
1709 dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx locked\n"); 2284 if (netif_msg_tx_queued(adapter))
2285 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
2286 "tx locked\n");
1710 return NETDEV_TX_LOCKED; 2287 return NETDEV_TX_LOCKED;
1711 } 2288 }
1712 2289
@@ -1714,22 +2291,26 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1714 /* not enough descriptors */ 2291 /* not enough descriptors */
1715 netif_stop_queue(netdev); 2292 netif_stop_queue(netdev);
1716 spin_unlock_irqrestore(&adapter->lock, flags); 2293 spin_unlock_irqrestore(&adapter->lock, flags);
1717 dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx busy\n"); 2294 if (netif_msg_tx_queued(adapter))
2295 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
2296 "tx busy\n");
1718 return NETDEV_TX_BUSY; 2297 return NETDEV_TX_BUSY;
1719 } 2298 }
1720 2299
1721 param.data = 0; 2300 ptpd = ATL1_TPD_DESC(tpd_ring,
2301 (u16) atomic_read(&tpd_ring->next_to_use));
2302 memset(ptpd, 0, sizeof(struct tx_packet_desc));
1722 2303
1723 if (adapter->vlgrp && vlan_tx_tag_present(skb)) { 2304 if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
1724 vlan_tag = vlan_tx_tag_get(skb); 2305 vlan_tag = vlan_tx_tag_get(skb);
1725 vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | 2306 vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
1726 ((vlan_tag >> 9) & 0x8); 2307 ((vlan_tag >> 9) & 0x8);
1727 param.csum.csumpl |= 1 << CSUM_PARAM_INSVLAG_SHIFT; 2308 ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
1728 param.csum.csumpu |= (vlan_tag & CSUM_PARAM_VALANTAG_MASK) << 2309 ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) <<
1729 CSUM_PARAM_VALAN_SHIFT; 2310 TPD_VL_TAGGED_SHIFT;
1730 } 2311 }
1731 2312
1732 tso = atl1_tso(adapter, skb, &param.tso); 2313 tso = atl1_tso(adapter, skb, ptpd);
1733 if (tso < 0) { 2314 if (tso < 0) {
1734 spin_unlock_irqrestore(&adapter->lock, flags); 2315 spin_unlock_irqrestore(&adapter->lock, flags);
1735 dev_kfree_skb_any(skb); 2316 dev_kfree_skb_any(skb);
@@ -1737,7 +2318,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1737 } 2318 }
1738 2319
1739 if (!tso) { 2320 if (!tso) {
1740 ret_val = atl1_tx_csum(adapter, skb, &param.csum); 2321 ret_val = atl1_tx_csum(adapter, skb, ptpd);
1741 if (ret_val < 0) { 2322 if (ret_val < 0) {
1742 spin_unlock_irqrestore(&adapter->lock, flags); 2323 spin_unlock_irqrestore(&adapter->lock, flags);
1743 dev_kfree_skb_any(skb); 2324 dev_kfree_skb_any(skb);
@@ -1745,13 +2326,11 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1745 } 2326 }
1746 } 2327 }
1747 2328
1748 val = (param.csum.csumpl >> CSUM_PARAM_SEGMENT_SHIFT) & 2329 atl1_tx_map(adapter, skb, ptpd);
1749 CSUM_PARAM_SEGMENT_MASK; 2330 atl1_tx_queue(adapter, count, ptpd);
1750 atl1_tx_map(adapter, skb, 1 == val);
1751 atl1_tx_queue(adapter, count, &param);
1752 netdev->trans_start = jiffies;
1753 spin_unlock_irqrestore(&adapter->lock, flags);
1754 atl1_update_mailbox(adapter); 2331 atl1_update_mailbox(adapter);
2332 spin_unlock_irqrestore(&adapter->lock, flags);
2333 netdev->trans_start = jiffies;
1755 return NETDEV_TX_OK; 2334 return NETDEV_TX_OK;
1756} 2335}
1757 2336
@@ -1776,7 +2355,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
1776 adapter->cmb.cmb->int_stats = 0; 2355 adapter->cmb.cmb->int_stats = 0;
1777 2356
1778 if (status & ISR_GPHY) /* clear phy status */ 2357 if (status & ISR_GPHY) /* clear phy status */
1779 atl1_clear_phy_int(adapter); 2358 atlx_clear_phy_int(adapter);
1780 2359
1781 /* clear ISR status, and Enable CMB DMA/Disable Interrupt */ 2360 /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
1782 iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR); 2361 iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
@@ -1787,8 +2366,9 @@ static irqreturn_t atl1_intr(int irq, void *data)
1787 2366
1788 /* check if PCIE PHY Link down */ 2367 /* check if PCIE PHY Link down */
1789 if (status & ISR_PHY_LINKDOWN) { 2368 if (status & ISR_PHY_LINKDOWN) {
1790 dev_printk(KERN_DEBUG, &adapter->pdev->dev, 2369 if (netif_msg_intr(adapter))
1791 "pcie phy link down %x\n", status); 2370 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
2371 "pcie phy link down %x\n", status);
1792 if (netif_running(adapter->netdev)) { /* reset MAC */ 2372 if (netif_running(adapter->netdev)) { /* reset MAC */
1793 iowrite32(0, adapter->hw.hw_addr + REG_IMR); 2373 iowrite32(0, adapter->hw.hw_addr + REG_IMR);
1794 schedule_work(&adapter->pcie_dma_to_rst_task); 2374 schedule_work(&adapter->pcie_dma_to_rst_task);
@@ -1798,9 +2378,10 @@ static irqreturn_t atl1_intr(int irq, void *data)
1798 2378
1799 /* check if DMA read/write error ? */ 2379 /* check if DMA read/write error ? */
1800 if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) { 2380 if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
1801 dev_printk(KERN_DEBUG, &adapter->pdev->dev, 2381 if (netif_msg_intr(adapter))
1802 "pcie DMA r/w error (status = 0x%x)\n", 2382 dev_printk(KERN_DEBUG, &adapter->pdev->dev,
1803 status); 2383 "pcie DMA r/w error (status = 0x%x)\n",
2384 status);
1804 iowrite32(0, adapter->hw.hw_addr + REG_IMR); 2385 iowrite32(0, adapter->hw.hw_addr + REG_IMR);
1805 schedule_work(&adapter->pcie_dma_to_rst_task); 2386 schedule_work(&adapter->pcie_dma_to_rst_task);
1806 return IRQ_HANDLED; 2387 return IRQ_HANDLED;
@@ -1823,8 +2404,11 @@ static irqreturn_t atl1_intr(int irq, void *data)
1823 if (status & (ISR_RXF_OV | ISR_RFD_UNRUN | 2404 if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
1824 ISR_RRD_OV | ISR_HOST_RFD_UNRUN | 2405 ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
1825 ISR_HOST_RRD_OV)) 2406 ISR_HOST_RRD_OV))
1826 dev_printk(KERN_DEBUG, &adapter->pdev->dev, 2407 if (netif_msg_intr(adapter))
1827 "rx exception, ISR = 0x%x\n", status); 2408 dev_printk(KERN_DEBUG,
2409 &adapter->pdev->dev,
2410 "rx exception, ISR = 0x%x\n",
2411 status);
1828 atl1_intr_rx(adapter); 2412 atl1_intr_rx(adapter);
1829 } 2413 }
1830 2414
@@ -1863,23 +2447,12 @@ static void atl1_phy_config(unsigned long data)
1863 spin_lock_irqsave(&adapter->lock, flags); 2447 spin_lock_irqsave(&adapter->lock, flags);
1864 adapter->phy_timer_pending = false; 2448 adapter->phy_timer_pending = false;
1865 atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg); 2449 atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
1866 atl1_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg); 2450 atl1_write_phy_reg(hw, MII_ATLX_CR, hw->mii_1000t_ctrl_reg);
1867 atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN); 2451 atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN);
1868 spin_unlock_irqrestore(&adapter->lock, flags); 2452 spin_unlock_irqrestore(&adapter->lock, flags);
1869} 2453}
1870 2454
1871/* 2455/*
1872 * atl1_tx_timeout - Respond to a Tx Hang
1873 * @netdev: network interface device structure
1874 */
1875static void atl1_tx_timeout(struct net_device *netdev)
1876{
1877 struct atl1_adapter *adapter = netdev_priv(netdev);
1878 /* Do the reset outside of interrupt context */
1879 schedule_work(&adapter->tx_timeout_task);
1880}
1881
1882/*
1883 * Orphaned vendor comment left intact here: 2456 * Orphaned vendor comment left intact here:
1884 * <vendor comment> 2457 * <vendor comment>
1885 * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT 2458 * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
@@ -1889,86 +2462,29 @@ static void atl1_tx_timeout(struct net_device *netdev)
1889 * assert again and again. 2462 * assert again and again.
1890 * </vendor comment> 2463 * </vendor comment>
1891 */ 2464 */
1892static void atl1_tx_timeout_task(struct work_struct *work)
1893{
1894 struct atl1_adapter *adapter =
1895 container_of(work, struct atl1_adapter, tx_timeout_task);
1896 struct net_device *netdev = adapter->netdev;
1897 2465
1898 netif_device_detach(netdev); 2466static int atl1_reset(struct atl1_adapter *adapter)
1899 atl1_down(adapter);
1900 atl1_up(adapter);
1901 netif_device_attach(netdev);
1902}
1903
1904/*
1905 * atl1_link_chg_task - deal with link change event Out of interrupt context
1906 */
1907static void atl1_link_chg_task(struct work_struct *work)
1908{
1909 struct atl1_adapter *adapter =
1910 container_of(work, struct atl1_adapter, link_chg_task);
1911 unsigned long flags;
1912
1913 spin_lock_irqsave(&adapter->lock, flags);
1914 atl1_check_link(adapter);
1915 spin_unlock_irqrestore(&adapter->lock, flags);
1916}
1917
1918static void atl1_vlan_rx_register(struct net_device *netdev,
1919 struct vlan_group *grp)
1920{
1921 struct atl1_adapter *adapter = netdev_priv(netdev);
1922 unsigned long flags;
1923 u32 ctrl;
1924
1925 spin_lock_irqsave(&adapter->lock, flags);
1926 /* atl1_irq_disable(adapter); */
1927 adapter->vlgrp = grp;
1928
1929 if (grp) {
1930 /* enable VLAN tag insert/strip */
1931 ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
1932 ctrl |= MAC_CTRL_RMV_VLAN;
1933 iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
1934 } else {
1935 /* disable VLAN tag insert/strip */
1936 ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
1937 ctrl &= ~MAC_CTRL_RMV_VLAN;
1938 iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
1939 }
1940
1941 /* atl1_irq_enable(adapter); */
1942 spin_unlock_irqrestore(&adapter->lock, flags);
1943}
1944
1945static void atl1_restore_vlan(struct atl1_adapter *adapter)
1946{
1947 atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp);
1948}
1949
1950int atl1_reset(struct atl1_adapter *adapter)
1951{ 2467{
1952 int ret; 2468 int ret;
1953
1954 ret = atl1_reset_hw(&adapter->hw); 2469 ret = atl1_reset_hw(&adapter->hw);
1955 if (ret != ATL1_SUCCESS) 2470 if (ret)
1956 return ret; 2471 return ret;
1957 return atl1_init_hw(&adapter->hw); 2472 return atl1_init_hw(&adapter->hw);
1958} 2473}
1959 2474
1960s32 atl1_up(struct atl1_adapter *adapter) 2475static s32 atl1_up(struct atl1_adapter *adapter)
1961{ 2476{
1962 struct net_device *netdev = adapter->netdev; 2477 struct net_device *netdev = adapter->netdev;
1963 int err; 2478 int err;
1964 int irq_flags = IRQF_SAMPLE_RANDOM; 2479 int irq_flags = IRQF_SAMPLE_RANDOM;
1965 2480
1966 /* hardware has been reset, we need to reload some things */ 2481 /* hardware has been reset, we need to reload some things */
1967 atl1_set_multi(netdev); 2482 atlx_set_multi(netdev);
1968 atl1_init_ring_ptrs(adapter); 2483 atl1_init_ring_ptrs(adapter);
1969 atl1_restore_vlan(adapter); 2484 atlx_restore_vlan(adapter);
1970 err = atl1_alloc_rx_buffers(adapter); 2485 err = atl1_alloc_rx_buffers(adapter);
1971 if (unlikely(!err)) /* no RX BUFFER allocated */ 2486 if (unlikely(!err))
2487 /* no RX BUFFER allocated */
1972 return -ENOMEM; 2488 return -ENOMEM;
1973 2489
1974 if (unlikely(atl1_configure(adapter))) { 2490 if (unlikely(atl1_configure(adapter))) {
@@ -1978,8 +2494,9 @@ s32 atl1_up(struct atl1_adapter *adapter)
1978 2494
1979 err = pci_enable_msi(adapter->pdev); 2495 err = pci_enable_msi(adapter->pdev);
1980 if (err) { 2496 if (err) {
1981 dev_info(&adapter->pdev->dev, 2497 if (netif_msg_ifup(adapter))
1982 "Unable to enable MSI: %d\n", err); 2498 dev_info(&adapter->pdev->dev,
2499 "Unable to enable MSI: %d\n", err);
1983 irq_flags |= IRQF_SHARED; 2500 irq_flags |= IRQF_SHARED;
1984 } 2501 }
1985 2502
@@ -1989,7 +2506,7 @@ s32 atl1_up(struct atl1_adapter *adapter)
1989 goto err_up; 2506 goto err_up;
1990 2507
1991 mod_timer(&adapter->watchdog_timer, jiffies); 2508 mod_timer(&adapter->watchdog_timer, jiffies);
1992 atl1_irq_enable(adapter); 2509 atlx_irq_enable(adapter);
1993 atl1_check_link(adapter); 2510 atl1_check_link(adapter);
1994 return 0; 2511 return 0;
1995 2512
@@ -2000,7 +2517,7 @@ err_up:
2000 return err; 2517 return err;
2001} 2518}
2002 2519
2003void atl1_down(struct atl1_adapter *adapter) 2520static void atl1_down(struct atl1_adapter *adapter)
2004{ 2521{
2005 struct net_device *netdev = adapter->netdev; 2522 struct net_device *netdev = adapter->netdev;
2006 2523
@@ -2008,7 +2525,7 @@ void atl1_down(struct atl1_adapter *adapter)
2008 del_timer_sync(&adapter->phy_config_timer); 2525 del_timer_sync(&adapter->phy_config_timer);
2009 adapter->phy_timer_pending = false; 2526 adapter->phy_timer_pending = false;
2010 2527
2011 atl1_irq_disable(adapter); 2528 atlx_irq_disable(adapter);
2012 free_irq(adapter->pdev->irq, netdev); 2529 free_irq(adapter->pdev->irq, netdev);
2013 pci_disable_msi(adapter->pdev); 2530 pci_disable_msi(adapter->pdev);
2014 atl1_reset_hw(&adapter->hw); 2531 atl1_reset_hw(&adapter->hw);
@@ -2023,6 +2540,52 @@ void atl1_down(struct atl1_adapter *adapter)
2023 atl1_clean_rx_ring(adapter); 2540 atl1_clean_rx_ring(adapter);
2024} 2541}
2025 2542
2543static void atl1_tx_timeout_task(struct work_struct *work)
2544{
2545 struct atl1_adapter *adapter =
2546 container_of(work, struct atl1_adapter, tx_timeout_task);
2547 struct net_device *netdev = adapter->netdev;
2548
2549 netif_device_detach(netdev);
2550 atl1_down(adapter);
2551 atl1_up(adapter);
2552 netif_device_attach(netdev);
2553}
2554
2555/*
2556 * atl1_change_mtu - Change the Maximum Transfer Unit
2557 * @netdev: network interface device structure
2558 * @new_mtu: new value for maximum frame size
2559 *
2560 * Returns 0 on success, negative on failure
2561 */
2562static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
2563{
2564 struct atl1_adapter *adapter = netdev_priv(netdev);
2565 int old_mtu = netdev->mtu;
2566 int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
2567
2568 if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
2569 (max_frame > MAX_JUMBO_FRAME_SIZE)) {
2570 if (netif_msg_link(adapter))
2571 dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
2572 return -EINVAL;
2573 }
2574
2575 adapter->hw.max_frame_size = max_frame;
2576 adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3;
2577 adapter->rx_buffer_len = (max_frame + 7) & ~7;
2578 adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8;
2579
2580 netdev->mtu = new_mtu;
2581 if ((old_mtu != new_mtu) && netif_running(netdev)) {
2582 atl1_down(adapter);
2583 atl1_up(adapter);
2584 }
2585
2586 return 0;
2587}
2588
2026/* 2589/*
2027 * atl1_open - Called when a network interface is made active 2590 * atl1_open - Called when a network interface is made active
2028 * @netdev: network interface device structure 2591 * @netdev: network interface device structure
@@ -2091,7 +2654,7 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
2091 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2654 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2092 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); 2655 atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
2093 if (ctrl & BMSR_LSTATUS) 2656 if (ctrl & BMSR_LSTATUS)
2094 wufc &= ~ATL1_WUFC_LNKC; 2657 wufc &= ~ATLX_WUFC_LNKC;
2095 2658
2096 /* reduce speed to 10/100M */ 2659 /* reduce speed to 10/100M */
2097 if (wufc) { 2660 if (wufc) {
@@ -2099,15 +2662,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
2099 /* if resume, let driver to re- setup link */ 2662 /* if resume, let driver to re- setup link */
2100 hw->phy_configured = false; 2663 hw->phy_configured = false;
2101 atl1_set_mac_addr(hw); 2664 atl1_set_mac_addr(hw);
2102 atl1_set_multi(netdev); 2665 atlx_set_multi(netdev);
2103 2666
2104 ctrl = 0; 2667 ctrl = 0;
2105 /* turn on magic packet wol */ 2668 /* turn on magic packet wol */
2106 if (wufc & ATL1_WUFC_MAG) 2669 if (wufc & ATLX_WUFC_MAG)
2107 ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; 2670 ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
2108 2671
2109 /* turn on Link change WOL */ 2672 /* turn on Link change WOL */
2110 if (wufc & ATL1_WUFC_LNKC) 2673 if (wufc & ATLX_WUFC_LNKC)
2111 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); 2674 ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
2112 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); 2675 iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
2113 2676
@@ -2115,13 +2678,13 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
2115 ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); 2678 ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL);
2116 ctrl &= ~MAC_CTRL_DBG; 2679 ctrl &= ~MAC_CTRL_DBG;
2117 ctrl &= ~MAC_CTRL_PROMIS_EN; 2680 ctrl &= ~MAC_CTRL_PROMIS_EN;
2118 if (wufc & ATL1_WUFC_MC) 2681 if (wufc & ATLX_WUFC_MC)
2119 ctrl |= MAC_CTRL_MC_ALL_EN; 2682 ctrl |= MAC_CTRL_MC_ALL_EN;
2120 else 2683 else
2121 ctrl &= ~MAC_CTRL_MC_ALL_EN; 2684 ctrl &= ~MAC_CTRL_MC_ALL_EN;
2122 2685
2123 /* turn on broadcast mode if wake on-BC is enabled */ 2686 /* turn on broadcast mode if wake on-BC is enabled */
2124 if (wufc & ATL1_WUFC_BC) 2687 if (wufc & ATLX_WUFC_BC)
2125 ctrl |= MAC_CTRL_BC_EN; 2688 ctrl |= MAC_CTRL_BC_EN;
2126 else 2689 else
2127 ctrl &= ~MAC_CTRL_BC_EN; 2690 ctrl &= ~MAC_CTRL_BC_EN;
@@ -2149,12 +2712,13 @@ static int atl1_resume(struct pci_dev *pdev)
2149{ 2712{
2150 struct net_device *netdev = pci_get_drvdata(pdev); 2713 struct net_device *netdev = pci_get_drvdata(pdev);
2151 struct atl1_adapter *adapter = netdev_priv(netdev); 2714 struct atl1_adapter *adapter = netdev_priv(netdev);
2152 u32 ret_val; 2715 u32 err;
2153 2716
2154 pci_set_power_state(pdev, 0); 2717 pci_set_power_state(pdev, PCI_D0);
2155 pci_restore_state(pdev); 2718 pci_restore_state(pdev);
2156 2719
2157 ret_val = pci_enable_device(pdev); 2720 /* FIXME: check and handle */
2721 err = pci_enable_device(pdev);
2158 pci_enable_wake(pdev, PCI_D3hot, 0); 2722 pci_enable_wake(pdev, PCI_D3hot, 0);
2159 pci_enable_wake(pdev, PCI_D3cold, 0); 2723 pci_enable_wake(pdev, PCI_D3cold, 0);
2160 2724
@@ -2221,14 +2785,16 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2221 dev_err(&pdev->dev, "no usable DMA configuration\n"); 2785 dev_err(&pdev->dev, "no usable DMA configuration\n");
2222 goto err_dma; 2786 goto err_dma;
2223 } 2787 }
2224 /* Mark all PCI regions associated with PCI device 2788 /*
2789 * Mark all PCI regions associated with PCI device
2225 * pdev as being reserved by owner atl1_driver_name 2790 * pdev as being reserved by owner atl1_driver_name
2226 */ 2791 */
2227 err = pci_request_regions(pdev, atl1_driver_name); 2792 err = pci_request_regions(pdev, ATLX_DRIVER_NAME);
2228 if (err) 2793 if (err)
2229 goto err_request_regions; 2794 goto err_request_regions;
2230 2795
2231 /* Enables bus-mastering on the device and calls 2796 /*
2797 * Enables bus-mastering on the device and calls
2232 * pcibios_set_master to do the needed arch specific settings 2798 * pcibios_set_master to do the needed arch specific settings
2233 */ 2799 */
2234 pci_set_master(pdev); 2800 pci_set_master(pdev);
@@ -2245,6 +2811,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2245 adapter->netdev = netdev; 2811 adapter->netdev = netdev;
2246 adapter->pdev = pdev; 2812 adapter->pdev = pdev;
2247 adapter->hw.back = adapter; 2813 adapter->hw.back = adapter;
2814 adapter->msg_enable = netif_msg_init(debug, atl1_default_msg);
2248 2815
2249 adapter->hw.hw_addr = pci_iomap(pdev, 0, 0); 2816 adapter->hw.hw_addr = pci_iomap(pdev, 0, 0);
2250 if (!adapter->hw.hw_addr) { 2817 if (!adapter->hw.hw_addr) {
@@ -2254,7 +2821,8 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2254 /* get device revision number */ 2821 /* get device revision number */
2255 adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + 2822 adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
2256 (REG_MASTER_CTRL + 2)); 2823 (REG_MASTER_CTRL + 2));
2257 dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); 2824 if (netif_msg_probe(adapter))
2825 dev_info(&pdev->dev, "version %s\n", ATLX_DRIVER_VERSION);
2258 2826
2259 /* set default ring resource counts */ 2827 /* set default ring resource counts */
2260 adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD; 2828 adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD;
@@ -2269,17 +2837,17 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2269 netdev->open = &atl1_open; 2837 netdev->open = &atl1_open;
2270 netdev->stop = &atl1_close; 2838 netdev->stop = &atl1_close;
2271 netdev->hard_start_xmit = &atl1_xmit_frame; 2839 netdev->hard_start_xmit = &atl1_xmit_frame;
2272 netdev->get_stats = &atl1_get_stats; 2840 netdev->get_stats = &atlx_get_stats;
2273 netdev->set_multicast_list = &atl1_set_multi; 2841 netdev->set_multicast_list = &atlx_set_multi;
2274 netdev->set_mac_address = &atl1_set_mac; 2842 netdev->set_mac_address = &atl1_set_mac;
2275 netdev->change_mtu = &atl1_change_mtu; 2843 netdev->change_mtu = &atl1_change_mtu;
2276 netdev->do_ioctl = &atl1_ioctl; 2844 netdev->do_ioctl = &atlx_ioctl;
2277 netdev->tx_timeout = &atl1_tx_timeout; 2845 netdev->tx_timeout = &atlx_tx_timeout;
2278 netdev->watchdog_timeo = 5 * HZ; 2846 netdev->watchdog_timeo = 5 * HZ;
2279#ifdef CONFIG_NET_POLL_CONTROLLER 2847#ifdef CONFIG_NET_POLL_CONTROLLER
2280 netdev->poll_controller = atl1_poll_controller; 2848 netdev->poll_controller = atl1_poll_controller;
2281#endif 2849#endif
2282 netdev->vlan_rx_register = atl1_vlan_rx_register; 2850 netdev->vlan_rx_register = atlx_vlan_rx_register;
2283 2851
2284 netdev->ethtool_ops = &atl1_ethtool_ops; 2852 netdev->ethtool_ops = &atl1_ethtool_ops;
2285 adapter->bd_number = cards_found; 2853 adapter->bd_number = cards_found;
@@ -2292,13 +2860,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2292 netdev->features = NETIF_F_HW_CSUM; 2860 netdev->features = NETIF_F_HW_CSUM;
2293 netdev->features |= NETIF_F_SG; 2861 netdev->features |= NETIF_F_SG;
2294 netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); 2862 netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
2295 2863 netdev->features |= NETIF_F_TSO;
2296 /*
2297 * FIXME - Until tso performance gets fixed, disable the feature.
2298 * Enable it with ethtool -K if desired.
2299 */
2300 /* netdev->features |= NETIF_F_TSO; */
2301
2302 netdev->features |= NETIF_F_LLTX; 2864 netdev->features |= NETIF_F_LLTX;
2303 2865
2304 /* 2866 /*
@@ -2309,7 +2871,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2309 /* atl1_pcie_patch(adapter); */ 2871 /* atl1_pcie_patch(adapter); */
2310 2872
2311 /* really reset GPHY core */ 2873 /* really reset GPHY core */
2312 iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE); 2874 iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
2313 2875
2314 /* 2876 /*
2315 * reset the controller to 2877 * reset the controller to
@@ -2354,7 +2916,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
2354 2916
2355 INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); 2917 INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
2356 2918
2357 INIT_WORK(&adapter->link_chg_task, atl1_link_chg_task); 2919 INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
2358 2920
2359 INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); 2921 INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
2360 2922
@@ -2397,7 +2959,8 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
2397 2959
2398 adapter = netdev_priv(netdev); 2960 adapter = netdev_priv(netdev);
2399 2961
2400 /* Some atl1 boards lack persistent storage for their MAC, and get it 2962 /*
2963 * Some atl1 boards lack persistent storage for their MAC, and get it
2401 * from the BIOS during POST. If we've been messing with the MAC 2964 * from the BIOS during POST. If we've been messing with the MAC
2402 * address, we need to save the permanent one. 2965 * address, we need to save the permanent one.
2403 */ 2966 */
@@ -2407,7 +2970,7 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
2407 atl1_set_mac_addr(&adapter->hw); 2970 atl1_set_mac_addr(&adapter->hw);
2408 } 2971 }
2409 2972
2410 iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE); 2973 iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
2411 unregister_netdev(netdev); 2974 unregister_netdev(netdev);
2412 pci_iounmap(pdev, adapter->hw.hw_addr); 2975 pci_iounmap(pdev, adapter->hw.hw_addr);
2413 pci_release_regions(pdev); 2976 pci_release_regions(pdev);
@@ -2416,7 +2979,7 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
2416} 2979}
2417 2980
2418static struct pci_driver atl1_driver = { 2981static struct pci_driver atl1_driver = {
2419 .name = atl1_driver_name, 2982 .name = ATLX_DRIVER_NAME,
2420 .id_table = atl1_pci_tbl, 2983 .id_table = atl1_pci_tbl,
2421 .probe = atl1_probe, 2984 .probe = atl1_probe,
2422 .remove = __devexit_p(atl1_remove), 2985 .remove = __devexit_p(atl1_remove),
@@ -2448,3 +3011,554 @@ static int __init atl1_init_module(void)
2448 3011
2449module_init(atl1_init_module); 3012module_init(atl1_init_module);
2450module_exit(atl1_exit_module); 3013module_exit(atl1_exit_module);
3014
3015struct atl1_stats {
3016 char stat_string[ETH_GSTRING_LEN];
3017 int sizeof_stat;
3018 int stat_offset;
3019};
3020
3021#define ATL1_STAT(m) \
3022 sizeof(((struct atl1_adapter *)0)->m), offsetof(struct atl1_adapter, m)
3023
3024static struct atl1_stats atl1_gstrings_stats[] = {
3025 {"rx_packets", ATL1_STAT(soft_stats.rx_packets)},
3026 {"tx_packets", ATL1_STAT(soft_stats.tx_packets)},
3027 {"rx_bytes", ATL1_STAT(soft_stats.rx_bytes)},
3028 {"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)},
3029 {"rx_errors", ATL1_STAT(soft_stats.rx_errors)},
3030 {"tx_errors", ATL1_STAT(soft_stats.tx_errors)},
3031 {"rx_dropped", ATL1_STAT(net_stats.rx_dropped)},
3032 {"tx_dropped", ATL1_STAT(net_stats.tx_dropped)},
3033 {"multicast", ATL1_STAT(soft_stats.multicast)},
3034 {"collisions", ATL1_STAT(soft_stats.collisions)},
3035 {"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)},
3036 {"rx_over_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
3037 {"rx_crc_errors", ATL1_STAT(soft_stats.rx_crc_errors)},
3038 {"rx_frame_errors", ATL1_STAT(soft_stats.rx_frame_errors)},
3039 {"rx_fifo_errors", ATL1_STAT(soft_stats.rx_fifo_errors)},
3040 {"rx_missed_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
3041 {"tx_aborted_errors", ATL1_STAT(soft_stats.tx_aborted_errors)},
3042 {"tx_carrier_errors", ATL1_STAT(soft_stats.tx_carrier_errors)},
3043 {"tx_fifo_errors", ATL1_STAT(soft_stats.tx_fifo_errors)},
3044 {"tx_window_errors", ATL1_STAT(soft_stats.tx_window_errors)},
3045 {"tx_abort_exce_coll", ATL1_STAT(soft_stats.excecol)},
3046 {"tx_abort_late_coll", ATL1_STAT(soft_stats.latecol)},
3047 {"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)},
3048 {"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)},
3049 {"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)},
3050 {"tx_underun", ATL1_STAT(soft_stats.tx_underun)},
3051 {"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)},
3052 {"tx_pause", ATL1_STAT(soft_stats.tx_pause)},
3053 {"rx_pause", ATL1_STAT(soft_stats.rx_pause)},
3054 {"rx_rrd_ov", ATL1_STAT(soft_stats.rx_rrd_ov)},
3055 {"rx_trunc", ATL1_STAT(soft_stats.rx_trunc)}
3056};
3057
3058static void atl1_get_ethtool_stats(struct net_device *netdev,
3059 struct ethtool_stats *stats, u64 *data)
3060{
3061 struct atl1_adapter *adapter = netdev_priv(netdev);
3062 int i;
3063 char *p;
3064
3065 for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
3066 p = (char *)adapter+atl1_gstrings_stats[i].stat_offset;
3067 data[i] = (atl1_gstrings_stats[i].sizeof_stat ==
3068 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
3069 }
3070
3071}
3072
3073static int atl1_get_sset_count(struct net_device *netdev, int sset)
3074{
3075 switch (sset) {
3076 case ETH_SS_STATS:
3077 return ARRAY_SIZE(atl1_gstrings_stats);
3078 default:
3079 return -EOPNOTSUPP;
3080 }
3081}
3082
3083static int atl1_get_settings(struct net_device *netdev,
3084 struct ethtool_cmd *ecmd)
3085{
3086 struct atl1_adapter *adapter = netdev_priv(netdev);
3087 struct atl1_hw *hw = &adapter->hw;
3088
3089 ecmd->supported = (SUPPORTED_10baseT_Half |
3090 SUPPORTED_10baseT_Full |
3091 SUPPORTED_100baseT_Half |
3092 SUPPORTED_100baseT_Full |
3093 SUPPORTED_1000baseT_Full |
3094 SUPPORTED_Autoneg | SUPPORTED_TP);
3095 ecmd->advertising = ADVERTISED_TP;
3096 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
3097 hw->media_type == MEDIA_TYPE_1000M_FULL) {
3098 ecmd->advertising |= ADVERTISED_Autoneg;
3099 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR) {
3100 ecmd->advertising |= ADVERTISED_Autoneg;
3101 ecmd->advertising |=
3102 (ADVERTISED_10baseT_Half |
3103 ADVERTISED_10baseT_Full |
3104 ADVERTISED_100baseT_Half |
3105 ADVERTISED_100baseT_Full |
3106 ADVERTISED_1000baseT_Full);
3107 } else
3108 ecmd->advertising |= (ADVERTISED_1000baseT_Full);
3109 }
3110 ecmd->port = PORT_TP;
3111 ecmd->phy_address = 0;
3112 ecmd->transceiver = XCVR_INTERNAL;
3113
3114 if (netif_carrier_ok(adapter->netdev)) {
3115 u16 link_speed, link_duplex;
3116 atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
3117 ecmd->speed = link_speed;
3118 if (link_duplex == FULL_DUPLEX)
3119 ecmd->duplex = DUPLEX_FULL;
3120 else
3121 ecmd->duplex = DUPLEX_HALF;
3122 } else {
3123 ecmd->speed = -1;
3124 ecmd->duplex = -1;
3125 }
3126 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
3127 hw->media_type == MEDIA_TYPE_1000M_FULL)
3128 ecmd->autoneg = AUTONEG_ENABLE;
3129 else
3130 ecmd->autoneg = AUTONEG_DISABLE;
3131
3132 return 0;
3133}
3134
3135static int atl1_set_settings(struct net_device *netdev,
3136 struct ethtool_cmd *ecmd)
3137{
3138 struct atl1_adapter *adapter = netdev_priv(netdev);
3139 struct atl1_hw *hw = &adapter->hw;
3140 u16 phy_data;
3141 int ret_val = 0;
3142 u16 old_media_type = hw->media_type;
3143
3144 if (netif_running(adapter->netdev)) {
3145 if (netif_msg_link(adapter))
3146 dev_dbg(&adapter->pdev->dev,
3147 "ethtool shutting down adapter\n");
3148 atl1_down(adapter);
3149 }
3150
3151 if (ecmd->autoneg == AUTONEG_ENABLE)
3152 hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
3153 else {
3154 if (ecmd->speed == SPEED_1000) {
3155 if (ecmd->duplex != DUPLEX_FULL) {
3156 if (netif_msg_link(adapter))
3157 dev_warn(&adapter->pdev->dev,
3158 "1000M half is invalid\n");
3159 ret_val = -EINVAL;
3160 goto exit_sset;
3161 }
3162 hw->media_type = MEDIA_TYPE_1000M_FULL;
3163 } else if (ecmd->speed == SPEED_100) {
3164 if (ecmd->duplex == DUPLEX_FULL)
3165 hw->media_type = MEDIA_TYPE_100M_FULL;
3166 else
3167 hw->media_type = MEDIA_TYPE_100M_HALF;
3168 } else {
3169 if (ecmd->duplex == DUPLEX_FULL)
3170 hw->media_type = MEDIA_TYPE_10M_FULL;
3171 else
3172 hw->media_type = MEDIA_TYPE_10M_HALF;
3173 }
3174 }
3175 switch (hw->media_type) {
3176 case MEDIA_TYPE_AUTO_SENSOR:
3177 ecmd->advertising =
3178 ADVERTISED_10baseT_Half |
3179 ADVERTISED_10baseT_Full |
3180 ADVERTISED_100baseT_Half |
3181 ADVERTISED_100baseT_Full |
3182 ADVERTISED_1000baseT_Full |
3183 ADVERTISED_Autoneg | ADVERTISED_TP;
3184 break;
3185 case MEDIA_TYPE_1000M_FULL:
3186 ecmd->advertising =
3187 ADVERTISED_1000baseT_Full |
3188 ADVERTISED_Autoneg | ADVERTISED_TP;
3189 break;
3190 default:
3191 ecmd->advertising = 0;
3192 break;
3193 }
3194 if (atl1_phy_setup_autoneg_adv(hw)) {
3195 ret_val = -EINVAL;
3196 if (netif_msg_link(adapter))
3197 dev_warn(&adapter->pdev->dev,
3198 "invalid ethtool speed/duplex setting\n");
3199 goto exit_sset;
3200 }
3201 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
3202 hw->media_type == MEDIA_TYPE_1000M_FULL)
3203 phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
3204 else {
3205 switch (hw->media_type) {
3206 case MEDIA_TYPE_100M_FULL:
3207 phy_data =
3208 MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
3209 MII_CR_RESET;
3210 break;
3211 case MEDIA_TYPE_100M_HALF:
3212 phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
3213 break;
3214 case MEDIA_TYPE_10M_FULL:
3215 phy_data =
3216 MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
3217 break;
3218 default:
3219 /* MEDIA_TYPE_10M_HALF: */
3220 phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
3221 break;
3222 }
3223 }
3224 atl1_write_phy_reg(hw, MII_BMCR, phy_data);
3225exit_sset:
3226 if (ret_val)
3227 hw->media_type = old_media_type;
3228
3229 if (netif_running(adapter->netdev)) {
3230 if (netif_msg_link(adapter))
3231 dev_dbg(&adapter->pdev->dev,
3232 "ethtool starting adapter\n");
3233 atl1_up(adapter);
3234 } else if (!ret_val) {
3235 if (netif_msg_link(adapter))
3236 dev_dbg(&adapter->pdev->dev,
3237 "ethtool resetting adapter\n");
3238 atl1_reset(adapter);
3239 }
3240 return ret_val;
3241}
3242
3243static void atl1_get_drvinfo(struct net_device *netdev,
3244 struct ethtool_drvinfo *drvinfo)
3245{
3246 struct atl1_adapter *adapter = netdev_priv(netdev);
3247
3248 strncpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
3249 strncpy(drvinfo->version, ATLX_DRIVER_VERSION,
3250 sizeof(drvinfo->version));
3251 strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
3252 strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
3253 sizeof(drvinfo->bus_info));
3254 drvinfo->eedump_len = ATL1_EEDUMP_LEN;
3255}
3256
3257static void atl1_get_wol(struct net_device *netdev,
3258 struct ethtool_wolinfo *wol)
3259{
3260 struct atl1_adapter *adapter = netdev_priv(netdev);
3261
3262 wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
3263 wol->wolopts = 0;
3264 if (adapter->wol & ATLX_WUFC_EX)
3265 wol->wolopts |= WAKE_UCAST;
3266 if (adapter->wol & ATLX_WUFC_MC)
3267 wol->wolopts |= WAKE_MCAST;
3268 if (adapter->wol & ATLX_WUFC_BC)
3269 wol->wolopts |= WAKE_BCAST;
3270 if (adapter->wol & ATLX_WUFC_MAG)
3271 wol->wolopts |= WAKE_MAGIC;
3272 return;
3273}
3274
3275static int atl1_set_wol(struct net_device *netdev,
3276 struct ethtool_wolinfo *wol)
3277{
3278 struct atl1_adapter *adapter = netdev_priv(netdev);
3279
3280 if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
3281 return -EOPNOTSUPP;
3282 adapter->wol = 0;
3283 if (wol->wolopts & WAKE_UCAST)
3284 adapter->wol |= ATLX_WUFC_EX;
3285 if (wol->wolopts & WAKE_MCAST)
3286 adapter->wol |= ATLX_WUFC_MC;
3287 if (wol->wolopts & WAKE_BCAST)
3288 adapter->wol |= ATLX_WUFC_BC;
3289 if (wol->wolopts & WAKE_MAGIC)
3290 adapter->wol |= ATLX_WUFC_MAG;
3291 return 0;
3292}
3293
3294static u32 atl1_get_msglevel(struct net_device *netdev)
3295{
3296 struct atl1_adapter *adapter = netdev_priv(netdev);
3297 return adapter->msg_enable;
3298}
3299
3300static void atl1_set_msglevel(struct net_device *netdev, u32 value)
3301{
3302 struct atl1_adapter *adapter = netdev_priv(netdev);
3303 adapter->msg_enable = value;
3304}
3305
3306static int atl1_get_regs_len(struct net_device *netdev)
3307{
3308 return ATL1_REG_COUNT * sizeof(u32);
3309}
3310
3311static void atl1_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
3312 void *p)
3313{
3314 struct atl1_adapter *adapter = netdev_priv(netdev);
3315 struct atl1_hw *hw = &adapter->hw;
3316 unsigned int i;
3317 u32 *regbuf = p;
3318
3319 for (i = 0; i < ATL1_REG_COUNT; i++) {
3320 /*
3321 * This switch statement avoids reserved regions
3322 * of register space.
3323 */
3324 switch (i) {
3325 case 6 ... 9:
3326 case 14:
3327 case 29 ... 31:
3328 case 34 ... 63:
3329 case 75 ... 127:
3330 case 136 ... 1023:
3331 case 1027 ... 1087:
3332 case 1091 ... 1151:
3333 case 1194 ... 1195:
3334 case 1200 ... 1201:
3335 case 1206 ... 1213:
3336 case 1216 ... 1279:
3337 case 1290 ... 1311:
3338 case 1323 ... 1343:
3339 case 1358 ... 1359:
3340 case 1368 ... 1375:
3341 case 1378 ... 1383:
3342 case 1388 ... 1391:
3343 case 1393 ... 1395:
3344 case 1402 ... 1403:
3345 case 1410 ... 1471:
3346 case 1522 ... 1535:
3347 /* reserved region; don't read it */
3348 regbuf[i] = 0;
3349 break;
3350 default:
3351 /* unreserved region */
3352 regbuf[i] = ioread32(hw->hw_addr + (i * sizeof(u32)));
3353 }
3354 }
3355}
3356
3357static void atl1_get_ringparam(struct net_device *netdev,
3358 struct ethtool_ringparam *ring)
3359{
3360 struct atl1_adapter *adapter = netdev_priv(netdev);
3361 struct atl1_tpd_ring *txdr = &adapter->tpd_ring;
3362 struct atl1_rfd_ring *rxdr = &adapter->rfd_ring;
3363
3364 ring->rx_max_pending = ATL1_MAX_RFD;
3365 ring->tx_max_pending = ATL1_MAX_TPD;
3366 ring->rx_mini_max_pending = 0;
3367 ring->rx_jumbo_max_pending = 0;
3368 ring->rx_pending = rxdr->count;
3369 ring->tx_pending = txdr->count;
3370 ring->rx_mini_pending = 0;
3371 ring->rx_jumbo_pending = 0;
3372}
3373
3374static int atl1_set_ringparam(struct net_device *netdev,
3375 struct ethtool_ringparam *ring)
3376{
3377 struct atl1_adapter *adapter = netdev_priv(netdev);
3378 struct atl1_tpd_ring *tpdr = &adapter->tpd_ring;
3379 struct atl1_rrd_ring *rrdr = &adapter->rrd_ring;
3380 struct atl1_rfd_ring *rfdr = &adapter->rfd_ring;
3381
3382 struct atl1_tpd_ring tpd_old, tpd_new;
3383 struct atl1_rfd_ring rfd_old, rfd_new;
3384 struct atl1_rrd_ring rrd_old, rrd_new;
3385 struct atl1_ring_header rhdr_old, rhdr_new;
3386 int err;
3387
3388 tpd_old = adapter->tpd_ring;
3389 rfd_old = adapter->rfd_ring;
3390 rrd_old = adapter->rrd_ring;
3391 rhdr_old = adapter->ring_header;
3392
3393 if (netif_running(adapter->netdev))
3394 atl1_down(adapter);
3395
3396 rfdr->count = (u16) max(ring->rx_pending, (u32) ATL1_MIN_RFD);
3397 rfdr->count = rfdr->count > ATL1_MAX_RFD ? ATL1_MAX_RFD :
3398 rfdr->count;
3399 rfdr->count = (rfdr->count + 3) & ~3;
3400 rrdr->count = rfdr->count;
3401
3402 tpdr->count = (u16) max(ring->tx_pending, (u32) ATL1_MIN_TPD);
3403 tpdr->count = tpdr->count > ATL1_MAX_TPD ? ATL1_MAX_TPD :
3404 tpdr->count;
3405 tpdr->count = (tpdr->count + 3) & ~3;
3406
3407 if (netif_running(adapter->netdev)) {
3408 /* try to get new resources before deleting old */
3409 err = atl1_setup_ring_resources(adapter);
3410 if (err)
3411 goto err_setup_ring;
3412
3413 /*
3414 * save the new, restore the old in order to free it,
3415 * then restore the new back again
3416 */
3417
3418 rfd_new = adapter->rfd_ring;
3419 rrd_new = adapter->rrd_ring;
3420 tpd_new = adapter->tpd_ring;
3421 rhdr_new = adapter->ring_header;
3422 adapter->rfd_ring = rfd_old;
3423 adapter->rrd_ring = rrd_old;
3424 adapter->tpd_ring = tpd_old;
3425 adapter->ring_header = rhdr_old;
3426 atl1_free_ring_resources(adapter);
3427 adapter->rfd_ring = rfd_new;
3428 adapter->rrd_ring = rrd_new;
3429 adapter->tpd_ring = tpd_new;
3430 adapter->ring_header = rhdr_new;
3431
3432 err = atl1_up(adapter);
3433 if (err)
3434 return err;
3435 }
3436 return 0;
3437
3438err_setup_ring:
3439 adapter->rfd_ring = rfd_old;
3440 adapter->rrd_ring = rrd_old;
3441 adapter->tpd_ring = tpd_old;
3442 adapter->ring_header = rhdr_old;
3443 atl1_up(adapter);
3444 return err;
3445}
3446
3447static void atl1_get_pauseparam(struct net_device *netdev,
3448 struct ethtool_pauseparam *epause)
3449{
3450 struct atl1_adapter *adapter = netdev_priv(netdev);
3451 struct atl1_hw *hw = &adapter->hw;
3452
3453 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
3454 hw->media_type == MEDIA_TYPE_1000M_FULL) {
3455 epause->autoneg = AUTONEG_ENABLE;
3456 } else {
3457 epause->autoneg = AUTONEG_DISABLE;
3458 }
3459 epause->rx_pause = 1;
3460 epause->tx_pause = 1;
3461}
3462
3463static int atl1_set_pauseparam(struct net_device *netdev,
3464 struct ethtool_pauseparam *epause)
3465{
3466 struct atl1_adapter *adapter = netdev_priv(netdev);
3467 struct atl1_hw *hw = &adapter->hw;
3468
3469 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
3470 hw->media_type == MEDIA_TYPE_1000M_FULL) {
3471 epause->autoneg = AUTONEG_ENABLE;
3472 } else {
3473 epause->autoneg = AUTONEG_DISABLE;
3474 }
3475
3476 epause->rx_pause = 1;
3477 epause->tx_pause = 1;
3478
3479 return 0;
3480}
3481
3482/* FIXME: is this right? -- CHS */
3483static u32 atl1_get_rx_csum(struct net_device *netdev)
3484{
3485 return 1;
3486}
3487
3488static void atl1_get_strings(struct net_device *netdev, u32 stringset,
3489 u8 *data)
3490{
3491 u8 *p = data;
3492 int i;
3493
3494 switch (stringset) {
3495 case ETH_SS_STATS:
3496 for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
3497 memcpy(p, atl1_gstrings_stats[i].stat_string,
3498 ETH_GSTRING_LEN);
3499 p += ETH_GSTRING_LEN;
3500 }
3501 break;
3502 }
3503}
3504
3505static int atl1_nway_reset(struct net_device *netdev)
3506{
3507 struct atl1_adapter *adapter = netdev_priv(netdev);
3508 struct atl1_hw *hw = &adapter->hw;
3509
3510 if (netif_running(netdev)) {
3511 u16 phy_data;
3512 atl1_down(adapter);
3513
3514 if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
3515 hw->media_type == MEDIA_TYPE_1000M_FULL) {
3516 phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
3517 } else {
3518 switch (hw->media_type) {
3519 case MEDIA_TYPE_100M_FULL:
3520 phy_data = MII_CR_FULL_DUPLEX |
3521 MII_CR_SPEED_100 | MII_CR_RESET;
3522 break;
3523 case MEDIA_TYPE_100M_HALF:
3524 phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
3525 break;
3526 case MEDIA_TYPE_10M_FULL:
3527 phy_data = MII_CR_FULL_DUPLEX |
3528 MII_CR_SPEED_10 | MII_CR_RESET;
3529 break;
3530 default:
3531 /* MEDIA_TYPE_10M_HALF */
3532 phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
3533 }
3534 }
3535 atl1_write_phy_reg(hw, MII_BMCR, phy_data);
3536 atl1_up(adapter);
3537 }
3538 return 0;
3539}
3540
3541const struct ethtool_ops atl1_ethtool_ops = {
3542 .get_settings = atl1_get_settings,
3543 .set_settings = atl1_set_settings,
3544 .get_drvinfo = atl1_get_drvinfo,
3545 .get_wol = atl1_get_wol,
3546 .set_wol = atl1_set_wol,
3547 .get_msglevel = atl1_get_msglevel,
3548 .set_msglevel = atl1_set_msglevel,
3549 .get_regs_len = atl1_get_regs_len,
3550 .get_regs = atl1_get_regs,
3551 .get_ringparam = atl1_get_ringparam,
3552 .set_ringparam = atl1_set_ringparam,
3553 .get_pauseparam = atl1_get_pauseparam,
3554 .set_pauseparam = atl1_set_pauseparam,
3555 .get_rx_csum = atl1_get_rx_csum,
3556 .set_tx_csum = ethtool_op_set_tx_hw_csum,
3557 .get_link = ethtool_op_get_link,
3558 .set_sg = ethtool_op_set_sg,
3559 .get_strings = atl1_get_strings,
3560 .nway_reset = atl1_nway_reset,
3561 .get_ethtool_stats = atl1_get_ethtool_stats,
3562 .get_sset_count = atl1_get_sset_count,
3563 .set_tso = ethtool_op_set_tso,
3564};
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
new file mode 100644
index 000000000000..51893d66eae1
--- /dev/null
+++ b/drivers/net/atlx/atl1.h
@@ -0,0 +1,796 @@
1/*
2 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
3 * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
4 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
5 *
6 * Derived from Intel e1000 driver
7 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#ifndef ATL1_H
25#define ATL1_H
26
27#include <linux/compiler.h>
28#include <linux/ethtool.h>
29#include <linux/if_vlan.h>
30#include <linux/mii.h>
31#include <linux/module.h>
32#include <linux/skbuff.h>
33#include <linux/spinlock.h>
34#include <linux/timer.h>
35#include <linux/types.h>
36#include <linux/workqueue.h>
37
38#include "atlx.h"
39
40#define ATLX_DRIVER_NAME "atl1"
41
42MODULE_DESCRIPTION("Atheros L1 Gigabit Ethernet Driver");
43
44#define atlx_adapter atl1_adapter
45#define atlx_check_for_link atl1_check_for_link
46#define atlx_check_link atl1_check_link
47#define atlx_hash_mc_addr atl1_hash_mc_addr
48#define atlx_hash_set atl1_hash_set
49#define atlx_hw atl1_hw
50#define atlx_mii_ioctl atl1_mii_ioctl
51#define atlx_read_phy_reg atl1_read_phy_reg
52#define atlx_set_mac atl1_set_mac
53#define atlx_set_mac_addr atl1_set_mac_addr
54
55struct atl1_adapter;
56struct atl1_hw;
57
58/* function prototypes needed by multiple files */
59u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
60void atl1_hash_set(struct atl1_hw *hw, u32 hash_value);
61s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data);
62void atl1_set_mac_addr(struct atl1_hw *hw);
63static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
64 int cmd);
65static u32 atl1_check_link(struct atl1_adapter *adapter);
66
67extern const struct ethtool_ops atl1_ethtool_ops;
68
69/* hardware definitions specific to L1 */
70
71/* Block IDLE Status Register */
72#define IDLE_STATUS_RXMAC 0x1
73#define IDLE_STATUS_TXMAC 0x2
74#define IDLE_STATUS_RXQ 0x4
75#define IDLE_STATUS_TXQ 0x8
76#define IDLE_STATUS_DMAR 0x10
77#define IDLE_STATUS_DMAW 0x20
78#define IDLE_STATUS_SMB 0x40
79#define IDLE_STATUS_CMB 0x80
80
81/* MDIO Control Register */
82#define MDIO_WAIT_TIMES 30
83
84/* MAC Control Register */
85#define MAC_CTRL_TX_PAUSE 0x10000
86#define MAC_CTRL_SCNT 0x20000
87#define MAC_CTRL_SRST_TX 0x40000
88#define MAC_CTRL_TX_SIMURST 0x80000
89#define MAC_CTRL_SPEED_SHIFT 20
90#define MAC_CTRL_SPEED_MASK 0x300000
91#define MAC_CTRL_SPEED_1000 0x2
92#define MAC_CTRL_SPEED_10_100 0x1
93#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000
94#define MAC_CTRL_TX_HUGE 0x800000
95#define MAC_CTRL_RX_CHKSUM_EN 0x1000000
96#define MAC_CTRL_DBG 0x8000000
97
98/* Wake-On-Lan control register */
99#define WOL_CLK_SWITCH_EN 0x8000
100#define WOL_PT5_EN 0x200000
101#define WOL_PT6_EN 0x400000
102#define WOL_PT5_MATCH 0x8000000
103#define WOL_PT6_MATCH 0x10000000
104
105/* WOL Length ( 2 DWORD ) */
106#define REG_WOL_PATTERN_LEN 0x14A4
107#define WOL_PT_LEN_MASK 0x7F
108#define WOL_PT0_LEN_SHIFT 0
109#define WOL_PT1_LEN_SHIFT 8
110#define WOL_PT2_LEN_SHIFT 16
111#define WOL_PT3_LEN_SHIFT 24
112#define WOL_PT4_LEN_SHIFT 0
113#define WOL_PT5_LEN_SHIFT 8
114#define WOL_PT6_LEN_SHIFT 16
115
116/* Internal SRAM Partition Registers, low 32 bits */
117#define REG_SRAM_RFD_LEN 0x1504
118#define REG_SRAM_RRD_ADDR 0x1508
119#define REG_SRAM_RRD_LEN 0x150C
120#define REG_SRAM_TPD_ADDR 0x1510
121#define REG_SRAM_TPD_LEN 0x1514
122#define REG_SRAM_TRD_ADDR 0x1518
123#define REG_SRAM_TRD_LEN 0x151C
124#define REG_SRAM_RXF_ADDR 0x1520
125#define REG_SRAM_RXF_LEN 0x1524
126#define REG_SRAM_TXF_ADDR 0x1528
127#define REG_SRAM_TXF_LEN 0x152C
128#define REG_SRAM_TCPH_PATH_ADDR 0x1530
129#define SRAM_TCPH_ADDR_MASK 0xFFF
130#define SRAM_TCPH_ADDR_SHIFT 0
131#define SRAM_PATH_ADDR_MASK 0xFFF
132#define SRAM_PATH_ADDR_SHIFT 16
133
134/* Load Ptr Register */
135#define REG_LOAD_PTR 0x1534
136
137/* Descriptor Control registers, low 32 bits */
138#define REG_DESC_RFD_ADDR_LO 0x1544
139#define REG_DESC_RRD_ADDR_LO 0x1548
140#define REG_DESC_TPD_ADDR_LO 0x154C
141#define REG_DESC_CMB_ADDR_LO 0x1550
142#define REG_DESC_SMB_ADDR_LO 0x1554
143#define REG_DESC_RFD_RRD_RING_SIZE 0x1558
144#define DESC_RFD_RING_SIZE_MASK 0x7FF
145#define DESC_RFD_RING_SIZE_SHIFT 0
146#define DESC_RRD_RING_SIZE_MASK 0x7FF
147#define DESC_RRD_RING_SIZE_SHIFT 16
148#define REG_DESC_TPD_RING_SIZE 0x155C
149#define DESC_TPD_RING_SIZE_MASK 0x3FF
150#define DESC_TPD_RING_SIZE_SHIFT 0
151
152/* TXQ Control Register */
153#define REG_TXQ_CTRL 0x1580
154#define TXQ_CTRL_TPD_BURST_NUM_SHIFT 0
155#define TXQ_CTRL_TPD_BURST_NUM_MASK 0x1F
156#define TXQ_CTRL_EN 0x20
157#define TXQ_CTRL_ENH_MODE 0x40
158#define TXQ_CTRL_TPD_FETCH_TH_SHIFT 8
159#define TXQ_CTRL_TPD_FETCH_TH_MASK 0x3F
160#define TXQ_CTRL_TXF_BURST_NUM_SHIFT 16
161#define TXQ_CTRL_TXF_BURST_NUM_MASK 0xFFFF
162
163/* Jumbo packet Threshold for task offload */
164#define REG_TX_JUMBO_TASK_TH_TPD_IPG 0x1584
165#define TX_JUMBO_TASK_TH_MASK 0x7FF
166#define TX_JUMBO_TASK_TH_SHIFT 0
167#define TX_TPD_MIN_IPG_MASK 0x1F
168#define TX_TPD_MIN_IPG_SHIFT 16
169
170/* RXQ Control Register */
171#define REG_RXQ_CTRL 0x15A0
172#define RXQ_CTRL_RFD_BURST_NUM_SHIFT 0
173#define RXQ_CTRL_RFD_BURST_NUM_MASK 0xFF
174#define RXQ_CTRL_RRD_BURST_THRESH_SHIFT 8
175#define RXQ_CTRL_RRD_BURST_THRESH_MASK 0xFF
176#define RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT 16
177#define RXQ_CTRL_RFD_PREF_MIN_IPG_MASK 0x1F
178#define RXQ_CTRL_CUT_THRU_EN 0x40000000
179#define RXQ_CTRL_EN 0x80000000
180
181/* Rx jumbo packet threshold and rrd retirement timer */
182#define REG_RXQ_JMBOSZ_RRDTIM 0x15A4
183#define RXQ_JMBOSZ_TH_MASK 0x7FF
184#define RXQ_JMBOSZ_TH_SHIFT 0
185#define RXQ_JMBO_LKAH_MASK 0xF
186#define RXQ_JMBO_LKAH_SHIFT 11
187#define RXQ_RRD_TIMER_MASK 0xFFFF
188#define RXQ_RRD_TIMER_SHIFT 16
189
190/* RFD flow control register */
191#define REG_RXQ_RXF_PAUSE_THRESH 0x15A8
192#define RXQ_RXF_PAUSE_TH_HI_SHIFT 16
193#define RXQ_RXF_PAUSE_TH_HI_MASK 0xFFF
194#define RXQ_RXF_PAUSE_TH_LO_SHIFT 0
195#define RXQ_RXF_PAUSE_TH_LO_MASK 0xFFF
196
197/* RRD flow control register */
198#define REG_RXQ_RRD_PAUSE_THRESH 0x15AC
199#define RXQ_RRD_PAUSE_TH_HI_SHIFT 0
200#define RXQ_RRD_PAUSE_TH_HI_MASK 0xFFF
201#define RXQ_RRD_PAUSE_TH_LO_SHIFT 16
202#define RXQ_RRD_PAUSE_TH_LO_MASK 0xFFF
203
204/* DMA Engine Control Register */
205#define REG_DMA_CTRL 0x15C0
206#define DMA_CTRL_DMAR_IN_ORDER 0x1
207#define DMA_CTRL_DMAR_ENH_ORDER 0x2
208#define DMA_CTRL_DMAR_OUT_ORDER 0x4
209#define DMA_CTRL_RCB_VALUE 0x8
210#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4
211#define DMA_CTRL_DMAR_BURST_LEN_MASK 7
212#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7
213#define DMA_CTRL_DMAW_BURST_LEN_MASK 7
214#define DMA_CTRL_DMAR_EN 0x400
215#define DMA_CTRL_DMAW_EN 0x800
216
217/* CMB/SMB Control Register */
218#define REG_CSMB_CTRL 0x15D0
219#define CSMB_CTRL_CMB_NOW 1
220#define CSMB_CTRL_SMB_NOW 2
221#define CSMB_CTRL_CMB_EN 4
222#define CSMB_CTRL_SMB_EN 8
223
224/* CMB DMA Write Threshold Register */
225#define REG_CMB_WRITE_TH 0x15D4
226#define CMB_RRD_TH_SHIFT 0
227#define CMB_RRD_TH_MASK 0x7FF
228#define CMB_TPD_TH_SHIFT 16
229#define CMB_TPD_TH_MASK 0x7FF
230
231/* RX/TX count-down timer to trigger CMB-write. 2us resolution. */
232#define REG_CMB_WRITE_TIMER 0x15D8
233#define CMB_RX_TM_SHIFT 0
234#define CMB_RX_TM_MASK 0xFFFF
235#define CMB_TX_TM_SHIFT 16
236#define CMB_TX_TM_MASK 0xFFFF
237
238/* Number of packet received since last CMB write */
239#define REG_CMB_RX_PKT_CNT 0x15DC
240
241/* Number of packet transmitted since last CMB write */
242#define REG_CMB_TX_PKT_CNT 0x15E0
243
244/* SMB auto DMA timer register */
245#define REG_SMB_TIMER 0x15E4
246
247/* Mailbox Register */
248#define REG_MAILBOX 0x15F0
249#define MB_RFD_PROD_INDX_SHIFT 0
250#define MB_RFD_PROD_INDX_MASK 0x7FF
251#define MB_RRD_CONS_INDX_SHIFT 11
252#define MB_RRD_CONS_INDX_MASK 0x7FF
253#define MB_TPD_PROD_INDX_SHIFT 22
254#define MB_TPD_PROD_INDX_MASK 0x3FF
255
256/* Interrupt Status Register */
257#define ISR_SMB 0x1
258#define ISR_TIMER 0x2
259#define ISR_MANUAL 0x4
260#define ISR_RXF_OV 0x8
261#define ISR_RFD_UNRUN 0x10
262#define ISR_RRD_OV 0x20
263#define ISR_TXF_UNRUN 0x40
264#define ISR_LINK 0x80
265#define ISR_HOST_RFD_UNRUN 0x100
266#define ISR_HOST_RRD_OV 0x200
267#define ISR_DMAR_TO_RST 0x400
268#define ISR_DMAW_TO_RST 0x800
269#define ISR_GPHY 0x1000
270#define ISR_RX_PKT 0x10000
271#define ISR_TX_PKT 0x20000
272#define ISR_TX_DMA 0x40000
273#define ISR_RX_DMA 0x80000
274#define ISR_CMB_RX 0x100000
275#define ISR_CMB_TX 0x200000
276#define ISR_MAC_RX 0x400000
277#define ISR_MAC_TX 0x800000
278#define ISR_DIS_SMB 0x20000000
279#define ISR_DIS_DMA 0x40000000
280
281/* Normal Interrupt mask */
282#define IMR_NORMAL_MASK (\
283 ISR_SMB |\
284 ISR_GPHY |\
285 ISR_PHY_LINKDOWN|\
286 ISR_DMAR_TO_RST |\
287 ISR_DMAW_TO_RST |\
288 ISR_CMB_TX |\
289 ISR_CMB_RX)
290
291/* Debug Interrupt Mask (enable all interrupt) */
292#define IMR_DEBUG_MASK (\
293 ISR_SMB |\
294 ISR_TIMER |\
295 ISR_MANUAL |\
296 ISR_RXF_OV |\
297 ISR_RFD_UNRUN |\
298 ISR_RRD_OV |\
299 ISR_TXF_UNRUN |\
300 ISR_LINK |\
301 ISR_CMB_TX |\
302 ISR_CMB_RX |\
303 ISR_RX_PKT |\
304 ISR_TX_PKT |\
305 ISR_MAC_RX |\
306 ISR_MAC_TX)
307
308#define MEDIA_TYPE_1000M_FULL 1
309#define MEDIA_TYPE_100M_FULL 2
310#define MEDIA_TYPE_100M_HALF 3
311#define MEDIA_TYPE_10M_FULL 4
312#define MEDIA_TYPE_10M_HALF 5
313
314#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* All but 1000-Half */
315
316#define MAX_JUMBO_FRAME_SIZE 10240
317
318#define ATL1_EEDUMP_LEN 48
319
320/* Statistics counters collected by the MAC */
321struct stats_msg_block {
322 /* rx */
323 u32 rx_ok; /* good RX packets */
324 u32 rx_bcast; /* good RX broadcast packets */
325 u32 rx_mcast; /* good RX multicast packets */
326 u32 rx_pause; /* RX pause frames */
327 u32 rx_ctrl; /* RX control packets other than pause frames */
328 u32 rx_fcs_err; /* RX packets with bad FCS */
329 u32 rx_len_err; /* RX packets with length != actual size */
330 u32 rx_byte_cnt; /* good bytes received. FCS is NOT included */
331 u32 rx_runt; /* RX packets < 64 bytes with good FCS */
332 u32 rx_frag; /* RX packets < 64 bytes with bad FCS */
333 u32 rx_sz_64; /* 64 byte RX packets */
334 u32 rx_sz_65_127;
335 u32 rx_sz_128_255;
336 u32 rx_sz_256_511;
337 u32 rx_sz_512_1023;
338 u32 rx_sz_1024_1518;
339 u32 rx_sz_1519_max; /* 1519 byte to MTU RX packets */
340 u32 rx_sz_ov; /* truncated RX packets > MTU */
341 u32 rx_rxf_ov; /* frames dropped due to RX FIFO overflow */
342 u32 rx_rrd_ov; /* frames dropped due to RRD overflow */
343 u32 rx_align_err; /* alignment errors */
344 u32 rx_bcast_byte_cnt; /* RX broadcast bytes, excluding FCS */
345 u32 rx_mcast_byte_cnt; /* RX multicast bytes, excluding FCS */
346 u32 rx_err_addr; /* packets dropped due to address filtering */
347
348 /* tx */
349 u32 tx_ok; /* good TX packets */
350 u32 tx_bcast; /* good TX broadcast packets */
351 u32 tx_mcast; /* good TX multicast packets */
352 u32 tx_pause; /* TX pause frames */
353 u32 tx_exc_defer; /* TX packets deferred excessively */
354 u32 tx_ctrl; /* TX control frames, excluding pause frames */
355 u32 tx_defer; /* TX packets deferred */
356 u32 tx_byte_cnt; /* bytes transmitted, FCS is NOT included */
357 u32 tx_sz_64; /* 64 byte TX packets */
358 u32 tx_sz_65_127;
359 u32 tx_sz_128_255;
360 u32 tx_sz_256_511;
361 u32 tx_sz_512_1023;
362 u32 tx_sz_1024_1518;
363 u32 tx_sz_1519_max; /* 1519 byte to MTU TX packets */
364 u32 tx_1_col; /* packets TX after a single collision */
365 u32 tx_2_col; /* packets TX after multiple collisions */
366 u32 tx_late_col; /* TX packets with late collisions */
367 u32 tx_abort_col; /* TX packets aborted w/excessive collisions */
368 u32 tx_underrun; /* TX packets aborted due to TX FIFO underrun
369 * or TRD FIFO underrun */
370 u32 tx_rd_eop; /* reads beyond the EOP into the next frame
371 * when TRD was not written timely */
372 u32 tx_len_err; /* TX packets where length != actual size */
373 u32 tx_trunc; /* TX packets truncated due to size > MTU */
374 u32 tx_bcast_byte; /* broadcast bytes transmitted, excluding FCS */
375 u32 tx_mcast_byte; /* multicast bytes transmitted, excluding FCS */
376 u32 smb_updated; /* 1: SMB Updated. This is used by software to
377 * indicate the statistics update. Software
378 * should clear this bit after retrieving the
379 * statistics information. */
380};
381
382/* Coalescing Message Block */
383struct coals_msg_block {
384 u32 int_stats; /* interrupt status */
385 u16 rrd_prod_idx; /* TRD Producer Index. */
386 u16 rfd_cons_idx; /* RFD Consumer Index. */
387 u16 update; /* Selene sets this bit every time it DMAs the
388 * CMB to host memory. Software should clear
389 * this bit when CMB info is processed. */
390 u16 tpd_cons_idx; /* TPD Consumer Index. */
391};
392
393/* RRD descriptor */
394struct rx_return_desc {
395 u8 num_buf; /* Number of RFD buffers used by the received packet */
396 u8 resved;
397 u16 buf_indx; /* RFD Index of the first buffer */
398 union {
399 u32 valid;
400 struct {
401 u16 rx_chksum;
402 u16 pkt_size;
403 } xsum_sz;
404 } xsz;
405
406 u16 pkt_flg; /* Packet flags */
407 u16 err_flg; /* Error flags */
408 u16 resved2;
409 u16 vlan_tag; /* VLAN TAG */
410};
411
412#define PACKET_FLAG_ETH_TYPE 0x0080
413#define PACKET_FLAG_VLAN_INS 0x0100
414#define PACKET_FLAG_ERR 0x0200
415#define PACKET_FLAG_IPV4 0x0400
416#define PACKET_FLAG_UDP 0x0800
417#define PACKET_FLAG_TCP 0x1000
418#define PACKET_FLAG_BCAST 0x2000
419#define PACKET_FLAG_MCAST 0x4000
420#define PACKET_FLAG_PAUSE 0x8000
421
422#define ERR_FLAG_CRC 0x0001
423#define ERR_FLAG_CODE 0x0002
424#define ERR_FLAG_DRIBBLE 0x0004
425#define ERR_FLAG_RUNT 0x0008
426#define ERR_FLAG_OV 0x0010
427#define ERR_FLAG_TRUNC 0x0020
428#define ERR_FLAG_IP_CHKSUM 0x0040
429#define ERR_FLAG_L4_CHKSUM 0x0080
430#define ERR_FLAG_LEN 0x0100
431#define ERR_FLAG_DES_ADDR 0x0200
432
433/* RFD descriptor */
434struct rx_free_desc {
435 __le64 buffer_addr; /* Address of the descriptor's data buffer */
436 __le16 buf_len; /* Size of the receive buffer in host memory */
437 u16 coalese; /* Update consumer index to host after the
438 * reception of this frame */
439 /* __attribute__ ((packed)) is required */
440} __attribute__ ((packed));
441
442/*
443 * The L1 transmit packet descriptor is comprised of four 32-bit words.
444 *
445 * 31 0
446 * +---------------------------------------+
447 * | Word 0: Buffer addr lo |
448 * +---------------------------------------+
449 * | Word 1: Buffer addr hi |
450 * +---------------------------------------+
451 * | Word 2 |
452 * +---------------------------------------+
453 * | Word 3 |
454 * +---------------------------------------+
455 *
456 * Words 0 and 1 combine to form a 64-bit buffer address.
457 *
458 * Word 2 is self explanatory in the #define block below.
459 *
460 * Word 3 has two forms, depending upon the state of bits 3 and 4.
461 * If bits 3 and 4 are both zero, then bits 14:31 are unused by the
462 * hardware. Otherwise, if either bit 3 or 4 is set, the definition
463 * of bits 14:31 vary according to the following depiction.
464 *
465 * 0 End of packet 0 End of packet
466 * 1 Coalesce 1 Coalesce
467 * 2 Insert VLAN tag 2 Insert VLAN tag
468 * 3 Custom csum enable = 0 3 Custom csum enable = 1
469 * 4 Segment enable = 1 4 Segment enable = 0
470 * 5 Generate IP checksum 5 Generate IP checksum
471 * 6 Generate TCP checksum 6 Generate TCP checksum
472 * 7 Generate UDP checksum 7 Generate UDP checksum
473 * 8 VLAN tagged 8 VLAN tagged
474 * 9 Ethernet frame type 9 Ethernet frame type
475 * 10-+ 10-+
476 * 11 | IP hdr length (10:13) 11 | IP hdr length (10:13)
477 * 12 | (num 32-bit words) 12 | (num 32-bit words)
478 * 13-+ 13-+
479 * 14-+ 14 Unused
480 * 15 | TCP hdr length (14:17) 15 Unused
481 * 16 | (num 32-bit words) 16-+
482 * 17-+ 17 |
483 * 18 Header TPD flag 18 |
484 * 19-+ 19 | Payload offset
485 * 20 | 20 | (16:23)
486 * 21 | 21 |
487 * 22 | 22 |
488 * 23 | 23-+
489 * 24 | 24-+
490 * 25 | MSS (19:31) 25 |
491 * 26 | 26 |
492 * 27 | 27 | Custom csum offset
493 * 28 | 28 | (24:31)
494 * 29 | 29 |
495 * 30 | 30 |
496 * 31-+ 31-+
497 */
498
499/* tpd word 2 */
500#define TPD_BUFLEN_MASK 0x3FFF
501#define TPD_BUFLEN_SHIFT 0
502#define TPD_DMAINT_MASK 0x0001
503#define TPD_DMAINT_SHIFT 14
504#define TPD_PKTNT_MASK 0x0001
505#define TPD_PKTINT_SHIFT 15
506#define TPD_VLANTAG_MASK 0xFFFF
507#define TPD_VLAN_SHIFT 16
508
509/* tpd word 3 bits 0:13 */
510#define TPD_EOP_MASK 0x0001
511#define TPD_EOP_SHIFT 0
512#define TPD_COALESCE_MASK 0x0001
513#define TPD_COALESCE_SHIFT 1
514#define TPD_INS_VL_TAG_MASK 0x0001
515#define TPD_INS_VL_TAG_SHIFT 2
516#define TPD_CUST_CSUM_EN_MASK 0x0001
517#define TPD_CUST_CSUM_EN_SHIFT 3
518#define TPD_SEGMENT_EN_MASK 0x0001
519#define TPD_SEGMENT_EN_SHIFT 4
520#define TPD_IP_CSUM_MASK 0x0001
521#define TPD_IP_CSUM_SHIFT 5
522#define TPD_TCP_CSUM_MASK 0x0001
523#define TPD_TCP_CSUM_SHIFT 6
524#define TPD_UDP_CSUM_MASK 0x0001
525#define TPD_UDP_CSUM_SHIFT 7
526#define TPD_VL_TAGGED_MASK 0x0001
527#define TPD_VL_TAGGED_SHIFT 8
528#define TPD_ETHTYPE_MASK 0x0001
529#define TPD_ETHTYPE_SHIFT 9
530#define TPD_IPHL_MASK 0x000F
531#define TPD_IPHL_SHIFT 10
532
533/* tpd word 3 bits 14:31 if segment enabled */
534#define TPD_TCPHDRLEN_MASK 0x000F
535#define TPD_TCPHDRLEN_SHIFT 14
536#define TPD_HDRFLAG_MASK 0x0001
537#define TPD_HDRFLAG_SHIFT 18
538#define TPD_MSS_MASK 0x1FFF
539#define TPD_MSS_SHIFT 19
540
541/* tpd word 3 bits 16:31 if custom csum enabled */
542#define TPD_PLOADOFFSET_MASK 0x00FF
543#define TPD_PLOADOFFSET_SHIFT 16
544#define TPD_CCSUMOFFSET_MASK 0x00FF
545#define TPD_CCSUMOFFSET_SHIFT 24
546
547struct tx_packet_desc {
548 __le64 buffer_addr;
549 __le32 word2;
550 __le32 word3;
551};
552
553/* DMA Order Settings */
554enum atl1_dma_order {
555 atl1_dma_ord_in = 1,
556 atl1_dma_ord_enh = 2,
557 atl1_dma_ord_out = 4
558};
559
560enum atl1_dma_rcb {
561 atl1_rcb_64 = 0,
562 atl1_rcb_128 = 1
563};
564
565enum atl1_dma_req_block {
566 atl1_dma_req_128 = 0,
567 atl1_dma_req_256 = 1,
568 atl1_dma_req_512 = 2,
569 atl1_dma_req_1024 = 3,
570 atl1_dma_req_2048 = 4,
571 atl1_dma_req_4096 = 5
572};
573
574#define ATL1_MAX_INTR 3
575#define ATL1_MAX_TX_BUF_LEN 0x3000 /* 12288 bytes */
576
577#define ATL1_DEFAULT_TPD 256
578#define ATL1_MAX_TPD 1024
579#define ATL1_MIN_TPD 64
580#define ATL1_DEFAULT_RFD 512
581#define ATL1_MIN_RFD 128
582#define ATL1_MAX_RFD 2048
583#define ATL1_REG_COUNT 1538
584
585#define ATL1_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
586#define ATL1_RFD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_free_desc)
587#define ATL1_TPD_DESC(R, i) ATL1_GET_DESC(R, i, struct tx_packet_desc)
588#define ATL1_RRD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_return_desc)
589
590/*
591 * atl1_ring_header represents a single, contiguous block of DMA space
592 * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
593 * message blocks (cmb, smb) described below
594 */
595struct atl1_ring_header {
596 void *desc; /* virtual address */
597 dma_addr_t dma; /* physical address*/
598 unsigned int size; /* length in bytes */
599};
600
601/*
602 * atl1_buffer is wrapper around a pointer to a socket buffer
603 * so a DMA handle can be stored along with the skb
604 */
605struct atl1_buffer {
606 struct sk_buff *skb; /* socket buffer */
607 u16 length; /* rx buffer length */
608 u16 alloced; /* 1 if skb allocated */
609 dma_addr_t dma;
610};
611
612/* transmit packet descriptor (tpd) ring */
613struct atl1_tpd_ring {
614 void *desc; /* descriptor ring virtual address */
615 dma_addr_t dma; /* descriptor ring physical address */
616 u16 size; /* descriptor ring length in bytes */
617 u16 count; /* number of descriptors in the ring */
618 u16 hw_idx; /* hardware index */
619 atomic_t next_to_clean;
620 atomic_t next_to_use;
621 struct atl1_buffer *buffer_info;
622};
623
624/* receive free descriptor (rfd) ring */
625struct atl1_rfd_ring {
626 void *desc; /* descriptor ring virtual address */
627 dma_addr_t dma; /* descriptor ring physical address */
628 u16 size; /* descriptor ring length in bytes */
629 u16 count; /* number of descriptors in the ring */
630 atomic_t next_to_use;
631 u16 next_to_clean;
632 struct atl1_buffer *buffer_info;
633};
634
635/* receive return descriptor (rrd) ring */
636struct atl1_rrd_ring {
637 void *desc; /* descriptor ring virtual address */
638 dma_addr_t dma; /* descriptor ring physical address */
639 unsigned int size; /* descriptor ring length in bytes */
640 u16 count; /* number of descriptors in the ring */
641 u16 next_to_use;
642 atomic_t next_to_clean;
643};
644
645/* coalescing message block (cmb) */
646struct atl1_cmb {
647 struct coals_msg_block *cmb;
648 dma_addr_t dma;
649};
650
651/* statistics message block (smb) */
652struct atl1_smb {
653 struct stats_msg_block *smb;
654 dma_addr_t dma;
655};
656
657/* Statistics counters */
658struct atl1_sft_stats {
659 u64 rx_packets;
660 u64 tx_packets;
661 u64 rx_bytes;
662 u64 tx_bytes;
663 u64 multicast;
664 u64 collisions;
665 u64 rx_errors;
666 u64 rx_length_errors;
667 u64 rx_crc_errors;
668 u64 rx_frame_errors;
669 u64 rx_fifo_errors;
670 u64 rx_missed_errors;
671 u64 tx_errors;
672 u64 tx_fifo_errors;
673 u64 tx_aborted_errors;
674 u64 tx_window_errors;
675 u64 tx_carrier_errors;
676 u64 tx_pause; /* TX pause frames */
677 u64 excecol; /* TX packets w/ excessive collisions */
678 u64 deffer; /* TX packets deferred */
679 u64 scc; /* packets TX after a single collision */
680 u64 mcc; /* packets TX after multiple collisions */
681 u64 latecol; /* TX packets w/ late collisions */
682 u64 tx_underun; /* TX packets aborted due to TX FIFO underrun
683 * or TRD FIFO underrun */
684 u64 tx_trunc; /* TX packets truncated due to size > MTU */
685 u64 rx_pause; /* num Pause packets received. */
686 u64 rx_rrd_ov;
687 u64 rx_trunc;
688};
689
690/* hardware structure */
691struct atl1_hw {
692 u8 __iomem *hw_addr;
693 struct atl1_adapter *back;
694 enum atl1_dma_order dma_ord;
695 enum atl1_dma_rcb rcb_value;
696 enum atl1_dma_req_block dmar_block;
697 enum atl1_dma_req_block dmaw_block;
698 u8 preamble_len;
699 u8 max_retry;
700 u8 jam_ipg; /* IPG to start JAM for collision based flow
701 * control in half-duplex mode. In units of
702 * 8-bit time */
703 u8 ipgt; /* Desired back to back inter-packet gap.
704 * The default is 96-bit time */
705 u8 min_ifg; /* Minimum number of IFG to enforce in between
706 * receive frames. Frame gap below such IFP
707 * is dropped */
708 u8 ipgr1; /* 64bit Carrier-Sense window */
709 u8 ipgr2; /* 96-bit IPG window */
710 u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned
711 * burst. Each TPD is 16 bytes long */
712 u8 rfd_burst; /* Number of RFD to prefetch in cache-aligned
713 * burst. Each RFD is 12 bytes long */
714 u8 rfd_fetch_gap;
715 u8 rrd_burst; /* Threshold number of RRDs that can be retired
716 * in a burst. Each RRD is 16 bytes long */
717 u8 tpd_fetch_th;
718 u8 tpd_fetch_gap;
719 u16 tx_jumbo_task_th;
720 u16 txf_burst; /* Number of data bytes to read in a cache-
721 * aligned burst. Each SRAM entry is 8 bytes */
722 u16 rx_jumbo_th; /* Jumbo packet size for non-VLAN packet. VLAN
723 * packets should add 4 bytes */
724 u16 rx_jumbo_lkah;
725 u16 rrd_ret_timer; /* RRD retirement timer. Decrement by 1 after
726 * every 512ns passes. */
727 u16 lcol; /* Collision Window */
728
729 u16 cmb_tpd;
730 u16 cmb_rrd;
731 u16 cmb_rx_timer;
732 u16 cmb_tx_timer;
733 u32 smb_timer;
734 u16 media_type;
735 u16 autoneg_advertised;
736
737 u16 mii_autoneg_adv_reg;
738 u16 mii_1000t_ctrl_reg;
739
740 u32 max_frame_size;
741 u32 min_frame_size;
742
743 u16 dev_rev;
744
745 /* spi flash */
746 u8 flash_vendor;
747
748 u8 mac_addr[ETH_ALEN];
749 u8 perm_mac_addr[ETH_ALEN];
750
751 bool phy_configured;
752};
753
754struct atl1_adapter {
755 struct net_device *netdev;
756 struct pci_dev *pdev;
757 struct net_device_stats net_stats;
758 struct atl1_sft_stats soft_stats;
759 struct vlan_group *vlgrp;
760 u32 rx_buffer_len;
761 u32 wol;
762 u16 link_speed;
763 u16 link_duplex;
764 spinlock_t lock;
765 struct work_struct tx_timeout_task;
766 struct work_struct link_chg_task;
767 struct work_struct pcie_dma_to_rst_task;
768 struct timer_list watchdog_timer;
769 struct timer_list phy_config_timer;
770 bool phy_timer_pending;
771
772 /* all descriptor rings' memory */
773 struct atl1_ring_header ring_header;
774
775 /* TX */
776 struct atl1_tpd_ring tpd_ring;
777 spinlock_t mb_lock;
778
779 /* RX */
780 struct atl1_rfd_ring rfd_ring;
781 struct atl1_rrd_ring rrd_ring;
782 u64 hw_csum_err;
783 u64 hw_csum_good;
784 u32 msg_enable;
785 u16 imt; /* interrupt moderator timer (2us resolution) */
786 u16 ict; /* interrupt clear timer (2us resolution */
787 struct mii_if_info mii; /* MII interface info */
788
789 u32 bd_number; /* board number */
790 bool pci_using_64;
791 struct atl1_hw hw;
792 struct atl1_smb smb;
793 struct atl1_cmb cmb;
794};
795
796#endif /* ATL1_H */
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
new file mode 100644
index 000000000000..4186326d1b94
--- /dev/null
+++ b/drivers/net/atlx/atlx.c
@@ -0,0 +1,433 @@
1/* atlx.c -- common functions for Attansic network drivers
2 *
3 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
4 * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
5 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
6 * Copyright(c) 2007 Atheros Corporation. All rights reserved.
7 *
8 * Derived from Intel e1000 driver
9 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc., 59
23 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25
26/* Including this file like a header is a temporary hack, I promise. -- CHS */
27#ifndef ATLX_C
28#define ATLX_C
29
30#include <linux/device.h>
31#include <linux/errno.h>
32#include <linux/etherdevice.h>
33#include <linux/if.h>
34#include <linux/netdevice.h>
35#include <linux/socket.h>
36#include <linux/sockios.h>
37#include <linux/spinlock.h>
38#include <linux/string.h>
39#include <linux/types.h>
40#include <linux/workqueue.h>
41
42#include "atlx.h"
43
44static struct atlx_spi_flash_dev flash_table[] = {
45/* MFR_NAME WRSR READ PRGM WREN WRDI RDSR RDID SEC_ERS CHIP_ERS */
46 {"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62},
47 {"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60},
48 {"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7},
49};
50
51static int atlx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
52{
53 switch (cmd) {
54 case SIOCGMIIPHY:
55 case SIOCGMIIREG:
56 case SIOCSMIIREG:
57 return atlx_mii_ioctl(netdev, ifr, cmd);
58 default:
59 return -EOPNOTSUPP;
60 }
61}
62
63/*
64 * atlx_set_mac - Change the Ethernet Address of the NIC
65 * @netdev: network interface device structure
66 * @p: pointer to an address structure
67 *
68 * Returns 0 on success, negative on failure
69 */
70static int atlx_set_mac(struct net_device *netdev, void *p)
71{
72 struct atlx_adapter *adapter = netdev_priv(netdev);
73 struct sockaddr *addr = p;
74
75 if (netif_running(netdev))
76 return -EBUSY;
77
78 if (!is_valid_ether_addr(addr->sa_data))
79 return -EADDRNOTAVAIL;
80
81 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
82 memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
83
84 atlx_set_mac_addr(&adapter->hw);
85 return 0;
86}
87
88static void atlx_check_for_link(struct atlx_adapter *adapter)
89{
90 struct net_device *netdev = adapter->netdev;
91 u16 phy_data = 0;
92
93 spin_lock(&adapter->lock);
94 adapter->phy_timer_pending = false;
95 atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
96 atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
97 spin_unlock(&adapter->lock);
98
99 /* notify upper layer link down ASAP */
100 if (!(phy_data & BMSR_LSTATUS)) {
101 /* Link Down */
102 if (netif_carrier_ok(netdev)) {
103 /* old link state: Up */
104 dev_info(&adapter->pdev->dev, "%s link is down\n",
105 netdev->name);
106 adapter->link_speed = SPEED_0;
107 netif_carrier_off(netdev);
108 netif_stop_queue(netdev);
109 }
110 }
111 schedule_work(&adapter->link_chg_task);
112}
113
114/*
115 * atlx_set_multi - Multicast and Promiscuous mode set
116 * @netdev: network interface device structure
117 *
118 * The set_multi entry point is called whenever the multicast address
119 * list or the network interface flags are updated. This routine is
120 * responsible for configuring the hardware for proper multicast,
121 * promiscuous mode, and all-multi behavior.
122 */
123static void atlx_set_multi(struct net_device *netdev)
124{
125 struct atlx_adapter *adapter = netdev_priv(netdev);
126 struct atlx_hw *hw = &adapter->hw;
127 struct dev_mc_list *mc_ptr;
128 u32 rctl;
129 u32 hash_value;
130
131 /* Check for Promiscuous and All Multicast modes */
132 rctl = ioread32(hw->hw_addr + REG_MAC_CTRL);
133 if (netdev->flags & IFF_PROMISC)
134 rctl |= MAC_CTRL_PROMIS_EN;
135 else if (netdev->flags & IFF_ALLMULTI) {
136 rctl |= MAC_CTRL_MC_ALL_EN;
137 rctl &= ~MAC_CTRL_PROMIS_EN;
138 } else
139 rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
140
141 iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL);
142
143 /* clear the old settings from the multicast hash table */
144 iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
145 iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
146
147 /* compute mc addresses' hash value ,and put it into hash table */
148 for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
149 hash_value = atlx_hash_mc_addr(hw, mc_ptr->dmi_addr);
150 atlx_hash_set(hw, hash_value);
151 }
152}
153
154/*
155 * atlx_irq_enable - Enable default interrupt generation settings
156 * @adapter: board private structure
157 */
158static void atlx_irq_enable(struct atlx_adapter *adapter)
159{
160 iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
161 ioread32(adapter->hw.hw_addr + REG_IMR);
162}
163
164/*
165 * atlx_irq_disable - Mask off interrupt generation on the NIC
166 * @adapter: board private structure
167 */
168static void atlx_irq_disable(struct atlx_adapter *adapter)
169{
170 iowrite32(0, adapter->hw.hw_addr + REG_IMR);
171 ioread32(adapter->hw.hw_addr + REG_IMR);
172 synchronize_irq(adapter->pdev->irq);
173}
174
175static void atlx_clear_phy_int(struct atlx_adapter *adapter)
176{
177 u16 phy_data;
178 unsigned long flags;
179
180 spin_lock_irqsave(&adapter->lock, flags);
181 atlx_read_phy_reg(&adapter->hw, 19, &phy_data);
182 spin_unlock_irqrestore(&adapter->lock, flags);
183}
184
185/*
186 * atlx_get_stats - Get System Network Statistics
187 * @netdev: network interface device structure
188 *
189 * Returns the address of the device statistics structure.
190 * The statistics are actually updated from the timer callback.
191 */
192static struct net_device_stats *atlx_get_stats(struct net_device *netdev)
193{
194 struct atlx_adapter *adapter = netdev_priv(netdev);
195 return &adapter->net_stats;
196}
197
198/*
199 * atlx_tx_timeout - Respond to a Tx Hang
200 * @netdev: network interface device structure
201 */
202static void atlx_tx_timeout(struct net_device *netdev)
203{
204 struct atlx_adapter *adapter = netdev_priv(netdev);
205 /* Do the reset outside of interrupt context */
206 schedule_work(&adapter->tx_timeout_task);
207}
208
209/*
210 * atlx_link_chg_task - deal with link change event Out of interrupt context
211 */
212static void atlx_link_chg_task(struct work_struct *work)
213{
214 struct atlx_adapter *adapter;
215 unsigned long flags;
216
217 adapter = container_of(work, struct atlx_adapter, link_chg_task);
218
219 spin_lock_irqsave(&adapter->lock, flags);
220 atlx_check_link(adapter);
221 spin_unlock_irqrestore(&adapter->lock, flags);
222}
223
224static void atlx_vlan_rx_register(struct net_device *netdev,
225 struct vlan_group *grp)
226{
227 struct atlx_adapter *adapter = netdev_priv(netdev);
228 unsigned long flags;
229 u32 ctrl;
230
231 spin_lock_irqsave(&adapter->lock, flags);
232 /* atlx_irq_disable(adapter); FIXME: confirm/remove */
233 adapter->vlgrp = grp;
234
235 if (grp) {
236 /* enable VLAN tag insert/strip */
237 ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
238 ctrl |= MAC_CTRL_RMV_VLAN;
239 iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
240 } else {
241 /* disable VLAN tag insert/strip */
242 ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
243 ctrl &= ~MAC_CTRL_RMV_VLAN;
244 iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
245 }
246
247 /* atlx_irq_enable(adapter); FIXME */
248 spin_unlock_irqrestore(&adapter->lock, flags);
249}
250
251static void atlx_restore_vlan(struct atlx_adapter *adapter)
252{
253 atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp);
254}
255
256/*
257 * This is the only thing that needs to be changed to adjust the
258 * maximum number of ports that the driver can manage.
259 */
260#define ATL1_MAX_NIC 4
261
262#define OPTION_UNSET -1
263#define OPTION_DISABLED 0
264#define OPTION_ENABLED 1
265
266#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }
267
268/*
269 * Interrupt Moderate Timer in units of 2 us
270 *
271 * Valid Range: 10-65535
272 *
273 * Default Value: 100 (200us)
274 */
275static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
276static int num_int_mod_timer;
277module_param_array_named(int_mod_timer, int_mod_timer, int,
278 &num_int_mod_timer, 0);
279MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
280
281/*
282 * flash_vendor
283 *
284 * Valid Range: 0-2
285 *
286 * 0 - Atmel
287 * 1 - SST
288 * 2 - ST
289 *
290 * Default Value: 0
291 */
292static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
293static int num_flash_vendor;
294module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0);
295MODULE_PARM_DESC(flash_vendor, "SPI flash vendor");
296
297#define DEFAULT_INT_MOD_CNT 100 /* 200us */
298#define MAX_INT_MOD_CNT 65000
299#define MIN_INT_MOD_CNT 50
300
301#define FLASH_VENDOR_DEFAULT 0
302#define FLASH_VENDOR_MIN 0
303#define FLASH_VENDOR_MAX 2
304
305struct atl1_option {
306 enum { enable_option, range_option, list_option } type;
307 char *name;
308 char *err;
309 int def;
310 union {
311 struct { /* range_option info */
312 int min;
313 int max;
314 } r;
315 struct { /* list_option info */
316 int nr;
317 struct atl1_opt_list {
318 int i;
319 char *str;
320 } *p;
321 } l;
322 } arg;
323};
324
325static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
326 struct pci_dev *pdev)
327{
328 if (*value == OPTION_UNSET) {
329 *value = opt->def;
330 return 0;
331 }
332
333 switch (opt->type) {
334 case enable_option:
335 switch (*value) {
336 case OPTION_ENABLED:
337 dev_info(&pdev->dev, "%s enabled\n", opt->name);
338 return 0;
339 case OPTION_DISABLED:
340 dev_info(&pdev->dev, "%s disabled\n", opt->name);
341 return 0;
342 }
343 break;
344 case range_option:
345 if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
346 dev_info(&pdev->dev, "%s set to %i\n", opt->name,
347 *value);
348 return 0;
349 }
350 break;
351 case list_option:{
352 int i;
353 struct atl1_opt_list *ent;
354
355 for (i = 0; i < opt->arg.l.nr; i++) {
356 ent = &opt->arg.l.p[i];
357 if (*value == ent->i) {
358 if (ent->str[0] != '\0')
359 dev_info(&pdev->dev, "%s\n",
360 ent->str);
361 return 0;
362 }
363 }
364 }
365 break;
366
367 default:
368 break;
369 }
370
371 dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
372 opt->name, *value, opt->err);
373 *value = opt->def;
374 return -1;
375}
376
377/*
378 * atl1_check_options - Range Checking for Command Line Parameters
379 * @adapter: board private structure
380 *
381 * This routine checks all command line parameters for valid user
382 * input. If an invalid value is given, or if no user specified
383 * value exists, a default value is used. The final value is stored
384 * in a variable in the adapter structure.
385 */
386void __devinit atl1_check_options(struct atl1_adapter *adapter)
387{
388 struct pci_dev *pdev = adapter->pdev;
389 int bd = adapter->bd_number;
390 if (bd >= ATL1_MAX_NIC) {
391 dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
392 dev_notice(&pdev->dev, "using defaults for all values\n");
393 }
394 { /* Interrupt Moderate Timer */
395 struct atl1_option opt = {
396 .type = range_option,
397 .name = "Interrupt Moderator Timer",
398 .err = "using default of "
399 __MODULE_STRING(DEFAULT_INT_MOD_CNT),
400 .def = DEFAULT_INT_MOD_CNT,
401 .arg = {.r = {.min = MIN_INT_MOD_CNT,
402 .max = MAX_INT_MOD_CNT} }
403 };
404 int val;
405 if (num_int_mod_timer > bd) {
406 val = int_mod_timer[bd];
407 atl1_validate_option(&val, &opt, pdev);
408 adapter->imt = (u16) val;
409 } else
410 adapter->imt = (u16) (opt.def);
411 }
412
413 { /* Flash Vendor */
414 struct atl1_option opt = {
415 .type = range_option,
416 .name = "SPI Flash Vendor",
417 .err = "using default of "
418 __MODULE_STRING(FLASH_VENDOR_DEFAULT),
419 .def = DEFAULT_INT_MOD_CNT,
420 .arg = {.r = {.min = FLASH_VENDOR_MIN,
421 .max = FLASH_VENDOR_MAX} }
422 };
423 int val;
424 if (num_flash_vendor > bd) {
425 val = flash_vendor[bd];
426 atl1_validate_option(&val, &opt, pdev);
427 adapter->hw.flash_vendor = (u8) val;
428 } else
429 adapter->hw.flash_vendor = (u8) (opt.def);
430 }
431}
432
433#endif /* ATLX_C */
diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h
new file mode 100644
index 000000000000..3be7c09734d4
--- /dev/null
+++ b/drivers/net/atlx/atlx.h
@@ -0,0 +1,506 @@
1/* atlx_hw.h -- common hardware definitions for Attansic network drivers
2 *
3 * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
4 * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
5 * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
6 * Copyright(c) 2007 Atheros Corporation. All rights reserved.
7 *
8 * Derived from Intel e1000 driver
9 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc., 59
23 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25
26#ifndef ATLX_H
27#define ATLX_H
28
29#include <linux/module.h>
30#include <linux/types.h>
31
32#define ATLX_DRIVER_VERSION "2.1.1"
33MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
34 Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
35MODULE_LICENSE("GPL");
36MODULE_VERSION(ATLX_DRIVER_VERSION);
37
38#define ATLX_ERR_PHY 2
39#define ATLX_ERR_PHY_SPEED 7
40#define ATLX_ERR_PHY_RES 8
41
42#define SPEED_0 0xffff
43#define SPEED_10 10
44#define SPEED_100 100
45#define SPEED_1000 1000
46#define HALF_DUPLEX 1
47#define FULL_DUPLEX 2
48
49#define MEDIA_TYPE_AUTO_SENSOR 0
50
51/* register definitions */
52#define REG_PM_CTRLSTAT 0x44
53
54#define REG_PCIE_CAP_LIST 0x58
55
56#define REG_VPD_CAP 0x6C
57#define VPD_CAP_ID_MASK 0xFF
58#define VPD_CAP_ID_SHIFT 0
59#define VPD_CAP_NEXT_PTR_MASK 0xFF
60#define VPD_CAP_NEXT_PTR_SHIFT 8
61#define VPD_CAP_VPD_ADDR_MASK 0x7FFF
62#define VPD_CAP_VPD_ADDR_SHIFT 16
63#define VPD_CAP_VPD_FLAG 0x80000000
64
65#define REG_VPD_DATA 0x70
66
67#define REG_SPI_FLASH_CTRL 0x200
68#define SPI_FLASH_CTRL_STS_NON_RDY 0x1
69#define SPI_FLASH_CTRL_STS_WEN 0x2
70#define SPI_FLASH_CTRL_STS_WPEN 0x80
71#define SPI_FLASH_CTRL_DEV_STS_MASK 0xFF
72#define SPI_FLASH_CTRL_DEV_STS_SHIFT 0
73#define SPI_FLASH_CTRL_INS_MASK 0x7
74#define SPI_FLASH_CTRL_INS_SHIFT 8
75#define SPI_FLASH_CTRL_START 0x800
76#define SPI_FLASH_CTRL_EN_VPD 0x2000
77#define SPI_FLASH_CTRL_LDSTART 0x8000
78#define SPI_FLASH_CTRL_CS_HI_MASK 0x3
79#define SPI_FLASH_CTRL_CS_HI_SHIFT 16
80#define SPI_FLASH_CTRL_CS_HOLD_MASK 0x3
81#define SPI_FLASH_CTRL_CS_HOLD_SHIFT 18
82#define SPI_FLASH_CTRL_CLK_LO_MASK 0x3
83#define SPI_FLASH_CTRL_CLK_LO_SHIFT 20
84#define SPI_FLASH_CTRL_CLK_HI_MASK 0x3
85#define SPI_FLASH_CTRL_CLK_HI_SHIFT 22
86#define SPI_FLASH_CTRL_CS_SETUP_MASK 0x3
87#define SPI_FLASH_CTRL_CS_SETUP_SHIFT 24
88#define SPI_FLASH_CTRL_EROM_PGSZ_MASK 0x3
89#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26
90#define SPI_FLASH_CTRL_WAIT_READY 0x10000000
91
92#define REG_SPI_ADDR 0x204
93
94#define REG_SPI_DATA 0x208
95
96#define REG_SPI_FLASH_CONFIG 0x20C
97#define SPI_FLASH_CONFIG_LD_ADDR_MASK 0xFFFFFF
98#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0
99#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3
100#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24
101#define SPI_FLASH_CONFIG_LD_EXIST 0x4000000
102
103#define REG_SPI_FLASH_OP_PROGRAM 0x210
104#define REG_SPI_FLASH_OP_SC_ERASE 0x211
105#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212
106#define REG_SPI_FLASH_OP_RDID 0x213
107#define REG_SPI_FLASH_OP_WREN 0x214
108#define REG_SPI_FLASH_OP_RDSR 0x215
109#define REG_SPI_FLASH_OP_WRSR 0x216
110#define REG_SPI_FLASH_OP_READ 0x217
111
112#define REG_TWSI_CTRL 0x218
113#define TWSI_CTRL_LD_OFFSET_MASK 0xFF
114#define TWSI_CTRL_LD_OFFSET_SHIFT 0
115#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7
116#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8
117#define TWSI_CTRL_SW_LDSTART 0x800
118#define TWSI_CTRL_HW_LDSTART 0x1000
119#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F
120#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15
121#define TWSI_CTRL_LD_EXIST 0x400000
122#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3
123#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23
124#define TWSI_CTRL_FREQ_SEL_100K 0
125#define TWSI_CTRL_FREQ_SEL_200K 1
126#define TWSI_CTRL_FREQ_SEL_300K 2
127#define TWSI_CTRL_FREQ_SEL_400K 3
128#define TWSI_CTRL_SMB_SLV_ADDR /* FIXME: define or remove */
129#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3
130#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24
131
132#define REG_PCIE_DEV_MISC_CTRL 0x21C
133#define PCIE_DEV_MISC_CTRL_EXT_PIPE 0x2
134#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1
135#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4
136#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN 0x8
137#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN 0x10
138
139#define REG_PCIE_PHYMISC 0x1000
140#define PCIE_PHYMISC_FORCE_RCV_DET 0x4
141
142#define REG_PCIE_DLL_TX_CTRL1 0x1104
143#define PCIE_DLL_TX_CTRL1_SEL_NOR_CLK 0x400
144#define PCIE_DLL_TX_CTRL1_DEF 0x568
145
146#define REG_LTSSM_TEST_MODE 0x12FC
147#define LTSSM_TEST_MODE_DEF 0x6500
148
149/* Master Control Register */
150#define REG_MASTER_CTRL 0x1400
151#define MASTER_CTRL_SOFT_RST 0x1
152#define MASTER_CTRL_MTIMER_EN 0x2
153#define MASTER_CTRL_ITIMER_EN 0x4
154#define MASTER_CTRL_MANUAL_INT 0x8
155#define MASTER_CTRL_REV_NUM_SHIFT 16
156#define MASTER_CTRL_REV_NUM_MASK 0xFF
157#define MASTER_CTRL_DEV_ID_SHIFT 24
158#define MASTER_CTRL_DEV_ID_MASK 0xFF
159
160/* Timer Initial Value Register */
161#define REG_MANUAL_TIMER_INIT 0x1404
162
163/* IRQ Moderator Timer Initial Value Register */
164#define REG_IRQ_MODU_TIMER_INIT 0x1408
165
166#define REG_PHY_ENABLE 0x140C
167
168/* IRQ Anti-Lost Timer Initial Value Register */
169#define REG_CMBDISDMA_TIMER 0x140E
170
171/* Block IDLE Status Register */
172#define REG_IDLE_STATUS 0x1410
173
174/* MDIO Control Register */
175#define REG_MDIO_CTRL 0x1414
176#define MDIO_DATA_MASK 0xFFFF
177#define MDIO_DATA_SHIFT 0
178#define MDIO_REG_ADDR_MASK 0x1F
179#define MDIO_REG_ADDR_SHIFT 16
180#define MDIO_RW 0x200000
181#define MDIO_SUP_PREAMBLE 0x400000
182#define MDIO_START 0x800000
183#define MDIO_CLK_SEL_SHIFT 24
184#define MDIO_CLK_25_4 0
185#define MDIO_CLK_25_6 2
186#define MDIO_CLK_25_8 3
187#define MDIO_CLK_25_10 4
188#define MDIO_CLK_25_14 5
189#define MDIO_CLK_25_20 6
190#define MDIO_CLK_25_28 7
191#define MDIO_BUSY 0x8000000
192
193/* MII PHY Status Register */
194#define REG_PHY_STATUS 0x1418
195
196/* BIST Control and Status Register0 (for the Packet Memory) */
197#define REG_BIST0_CTRL 0x141C
198#define BIST0_NOW 0x1
199#define BIST0_SRAM_FAIL 0x2
200#define BIST0_FUSE_FLAG 0x4
201#define REG_BIST1_CTRL 0x1420
202#define BIST1_NOW 0x1
203#define BIST1_SRAM_FAIL 0x2
204#define BIST1_FUSE_FLAG 0x4
205
206/* SerDes Lock Detect Control and Status Register */
207#define REG_SERDES_LOCK 0x1424
208#define SERDES_LOCK_DETECT 1
209#define SERDES_LOCK_DETECT_EN 2
210
211/* MAC Control Register */
212#define REG_MAC_CTRL 0x1480
213#define MAC_CTRL_TX_EN 1
214#define MAC_CTRL_RX_EN 2
215#define MAC_CTRL_TX_FLOW 4
216#define MAC_CTRL_RX_FLOW 8
217#define MAC_CTRL_LOOPBACK 0x10
218#define MAC_CTRL_DUPLX 0x20
219#define MAC_CTRL_ADD_CRC 0x40
220#define MAC_CTRL_PAD 0x80
221#define MAC_CTRL_LENCHK 0x100
222#define MAC_CTRL_HUGE_EN 0x200
223#define MAC_CTRL_PRMLEN_SHIFT 10
224#define MAC_CTRL_PRMLEN_MASK 0xF
225#define MAC_CTRL_RMV_VLAN 0x4000
226#define MAC_CTRL_PROMIS_EN 0x8000
227#define MAC_CTRL_MC_ALL_EN 0x2000000
228#define MAC_CTRL_BC_EN 0x4000000
229
230/* MAC IPG/IFG Control Register */
231#define REG_MAC_IPG_IFG 0x1484
232#define MAC_IPG_IFG_IPGT_SHIFT 0
233#define MAC_IPG_IFG_IPGT_MASK 0x7F
234#define MAC_IPG_IFG_MIFG_SHIFT 8
235#define MAC_IPG_IFG_MIFG_MASK 0xFF
236#define MAC_IPG_IFG_IPGR1_SHIFT 16
237#define MAC_IPG_IFG_IPGR1_MASK 0x7F
238#define MAC_IPG_IFG_IPGR2_SHIFT 24
239#define MAC_IPG_IFG_IPGR2_MASK 0x7F
240
241/* MAC STATION ADDRESS */
242#define REG_MAC_STA_ADDR 0x1488
243
244/* Hash table for multicast address */
245#define REG_RX_HASH_TABLE 0x1490
246
247/* MAC Half-Duplex Control Register */
248#define REG_MAC_HALF_DUPLX_CTRL 0x1498
249#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0
250#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3FF
251#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
252#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xF
253#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000
254#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000
255#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000
256#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000
257#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20
258#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xF
259#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24
260#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xF
261
262/* Maximum Frame Length Control Register */
263#define REG_MTU 0x149C
264
265/* Wake-On-Lan control register */
266#define REG_WOL_CTRL 0x14A0
267#define WOL_PATTERN_EN 0x1
268#define WOL_PATTERN_PME_EN 0x2
269#define WOL_MAGIC_EN 0x4
270#define WOL_MAGIC_PME_EN 0x8
271#define WOL_LINK_CHG_EN 0x10
272#define WOL_LINK_CHG_PME_EN 0x20
273#define WOL_PATTERN_ST 0x100
274#define WOL_MAGIC_ST 0x200
275#define WOL_LINKCHG_ST 0x400
276#define WOL_PT0_EN 0x10000
277#define WOL_PT1_EN 0x20000
278#define WOL_PT2_EN 0x40000
279#define WOL_PT3_EN 0x80000
280#define WOL_PT4_EN 0x100000
281#define WOL_PT0_MATCH 0x1000000
282#define WOL_PT1_MATCH 0x2000000
283#define WOL_PT2_MATCH 0x4000000
284#define WOL_PT3_MATCH 0x8000000
285#define WOL_PT4_MATCH 0x10000000
286
287/* Internal SRAM Partition Register, high 32 bits */
288#define REG_SRAM_RFD_ADDR 0x1500
289
290/* Descriptor Control register, high 32 bits */
291#define REG_DESC_BASE_ADDR_HI 0x1540
292
293/* Interrupt Status Register */
294#define REG_ISR 0x1600
295#define ISR_UR_DETECTED 0x1000000
296#define ISR_FERR_DETECTED 0x2000000
297#define ISR_NFERR_DETECTED 0x4000000
298#define ISR_CERR_DETECTED 0x8000000
299#define ISR_PHY_LINKDOWN 0x10000000
300#define ISR_DIS_INT 0x80000000
301
302/* Interrupt Mask Register */
303#define REG_IMR 0x1604
304
305#define REG_RFD_RRD_IDX 0x1800
306#define REG_TPD_IDX 0x1804
307
308/* MII definitions */
309
310/* PHY Common Register */
311#define MII_ATLX_CR 0x09
312#define MII_ATLX_SR 0x0A
313#define MII_ATLX_ESR 0x0F
314#define MII_ATLX_PSCR 0x10
315#define MII_ATLX_PSSR 0x11
316
317/* PHY Control Register */
318#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100,
319 * 00=10
320 */
321#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
322#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
323#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
324#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
325#define MII_CR_POWER_DOWN 0x0800 /* Power down */
326#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
327#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100,
328 * 00=10
329 */
330#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
331#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
332#define MII_CR_SPEED_MASK 0x2040
333#define MII_CR_SPEED_1000 0x0040
334#define MII_CR_SPEED_100 0x2000
335#define MII_CR_SPEED_10 0x0000
336
337/* PHY Status Register */
338#define MII_SR_EXTENDED_CAPS 0x0001 /* Ext register capabilities */
339#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
340#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
341#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
342#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
343#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
344#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
345#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext stat info in Reg 0x0F */
346#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
347#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
348#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
349#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
350#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
351#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
352#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
353
354/* Link partner ability register */
355#define MII_LPA_SLCT 0x001f /* Same as advertise selector */
356#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
357#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
358#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
359#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
360#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */
361#define MII_LPA_PAUSE 0x0400 /* PAUSE */
362#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */
363#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */
364#define MII_LPA_LPACK 0x4000 /* Link partner acked us */
365#define MII_LPA_NPAGE 0x8000 /* Next page bit */
366
367/* Autoneg Advertisement Register */
368#define MII_AR_SELECTOR_FIELD 0x0001 /* IEEE 802.3 CSMA/CD */
369#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
370#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
371#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
372#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
373#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
374#define MII_AR_PAUSE 0x0400 /* Pause operation desired */
375#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Dir bit */
376#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
377#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability support */
378#define MII_AR_SPEED_MASK 0x01E0
379#define MII_AR_DEFAULT_CAP_MASK 0x0DE0
380
381/* 1000BASE-T Control Register */
382#define MII_ATLX_CR_1000T_HD_CAPS 0x0100 /* Adv 1000T HD cap */
383#define MII_ATLX_CR_1000T_FD_CAPS 0x0200 /* Adv 1000T FD cap */
384#define MII_ATLX_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device,
385 * 0=DTE device */
386#define MII_ATLX_CR_1000T_MS_VALUE 0x0800 /* 1=Config PHY as Master,
387 * 0=Configure PHY as Slave */
388#define MII_ATLX_CR_1000T_MS_ENABLE 0x1000 /* 1=Man Master/Slave config,
389 * 0=Auto Master/Slave config
390 */
391#define MII_ATLX_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
392#define MII_ATLX_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
393#define MII_ATLX_CR_1000T_TEST_MODE_2 0x4000 /* Master Xmit Jitter test */
394#define MII_ATLX_CR_1000T_TEST_MODE_3 0x6000 /* Slave Xmit Jitter test */
395#define MII_ATLX_CR_1000T_TEST_MODE_4 0x8000 /* Xmitter Distortion test */
396#define MII_ATLX_CR_1000T_SPEED_MASK 0x0300
397#define MII_ATLX_CR_1000T_DEFAULT_CAP_MASK 0x0300
398
399/* 1000BASE-T Status Register */
400#define MII_ATLX_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
401#define MII_ATLX_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
402#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
403#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
404#define MII_ATLX_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master
405 * 0=Slave
406 */
407#define MII_ATLX_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config
408 * fault */
409#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS_SHIFT 12
410#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS_SHIFT 13
411
412/* Extended Status Register */
413#define MII_ATLX_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
414#define MII_ATLX_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
415#define MII_ATLX_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
416#define MII_ATLX_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
417
418/* ATLX PHY Specific Control Register */
419#define MII_ATLX_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Func disabled */
420#define MII_ATLX_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enbld */
421#define MII_ATLX_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
422#define MII_ATLX_PSCR_MAC_POWERDOWN 0x0008
423#define MII_ATLX_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low
424 * 0=CLK125 toggling
425 */
426#define MII_ATLX_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5,
427 * Manual MDI configuration
428 */
429#define MII_ATLX_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
430#define MII_ATLX_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover
431 * 100BASE-TX/10BASE-T: MDI
432 * Mode */
433#define MII_ATLX_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled
434 * all speeds.
435 */
436#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE 0x0080 /* 1=Enable Extended
437 * 10BASE-T distance
438 * (Lower 10BASE-T RX
439 * Threshold)
440 * 0=Normal 10BASE-T RX
441 * Threshold
442 */
443#define MII_ATLX_PSCR_MII_5BIT_ENABLE 0x0100 /* 1=5-Bit interface in
444 * 100BASE-TX
445 * 0=MII interface in
446 * 100BASE-TX
447 */
448#define MII_ATLX_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler dsbl */
449#define MII_ATLX_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
450#define MII_ATLX_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
451#define MII_ATLX_PSCR_POLARITY_REVERSAL_SHIFT 1
452#define MII_ATLX_PSCR_AUTO_X_MODE_SHIFT 5
453#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
454
455/* ATLX PHY Specific Status Register */
456#define MII_ATLX_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
457#define MII_ATLX_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
458#define MII_ATLX_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
459#define MII_ATLX_PSSR_10MBS 0x0000 /* 00=10Mbs */
460#define MII_ATLX_PSSR_100MBS 0x4000 /* 01=100Mbs */
461#define MII_ATLX_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
462
463/* PCI Command Register Bit Definitions */
464#define PCI_REG_COMMAND 0x04 /* PCI Command Register */
465#define CMD_IO_SPACE 0x0001
466#define CMD_MEMORY_SPACE 0x0002
467#define CMD_BUS_MASTER 0x0004
468
469/* Wake Up Filter Control */
470#define ATLX_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
471#define ATLX_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
472#define ATLX_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
473#define ATLX_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
474#define ATLX_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
475
476#define ADVERTISE_10_HALF 0x0001
477#define ADVERTISE_10_FULL 0x0002
478#define ADVERTISE_100_HALF 0x0004
479#define ADVERTISE_100_FULL 0x0008
480#define ADVERTISE_1000_HALF 0x0010
481#define ADVERTISE_1000_FULL 0x0020
482#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds */
483#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds */
484
485#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
486#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
487
488/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA */
489#define EEPROM_SUM 0xBABA
490#define NODE_ADDRESS_SIZE 6
491
492struct atlx_spi_flash_dev {
493 const char *manu_name; /* manufacturer id */
494 /* op-code */
495 u8 cmd_wrsr;
496 u8 cmd_read;
497 u8 cmd_program;
498 u8 cmd_wren;
499 u8 cmd_wrdi;
500 u8 cmd_rdsr;
501 u8 cmd_rdid;
502 u8 cmd_sector_erase;
503 u8 cmd_chip_erase;
504};
505
506#endif /* ATLX_H */
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index d0bf206632ca..d98113472a89 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -36,6 +36,9 @@
36#include "ixgbe_type.h" 36#include "ixgbe_type.h"
37#include "ixgbe_common.h" 37#include "ixgbe_common.h"
38 38
39#ifdef CONFIG_DCA
40#include <linux/dca.h>
41#endif
39 42
40#define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args) 43#define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args)
41 44
@@ -120,7 +123,6 @@ struct ixgbe_queue_stats {
120}; 123};
121 124
122struct ixgbe_ring { 125struct ixgbe_ring {
123 struct ixgbe_adapter *adapter; /* backlink */
124 void *desc; /* descriptor ring memory */ 126 void *desc; /* descriptor ring memory */
125 dma_addr_t dma; /* phys. address of descriptor ring */ 127 dma_addr_t dma; /* phys. address of descriptor ring */
126 unsigned int size; /* length in bytes */ 128 unsigned int size; /* length in bytes */
@@ -128,6 +130,7 @@ struct ixgbe_ring {
128 unsigned int next_to_use; 130 unsigned int next_to_use;
129 unsigned int next_to_clean; 131 unsigned int next_to_clean;
130 132
133 int queue_index; /* needed for multiqueue queue management */
131 union { 134 union {
132 struct ixgbe_tx_buffer *tx_buffer_info; 135 struct ixgbe_tx_buffer *tx_buffer_info;
133 struct ixgbe_rx_buffer *rx_buffer_info; 136 struct ixgbe_rx_buffer *rx_buffer_info;
@@ -136,8 +139,21 @@ struct ixgbe_ring {
136 u16 head; 139 u16 head;
137 u16 tail; 140 u16 tail;
138 141
142 unsigned int total_bytes;
143 unsigned int total_packets;
139 144
145 u16 reg_idx; /* holds the special value that gets the hardware register
146 * offset associated with this ring, which is different
147 * for DCE and RSS modes */
148
149#ifdef CONFIG_DCA
150 /* cpu for tx queue */
151 int cpu;
152#endif
140 struct ixgbe_queue_stats stats; 153 struct ixgbe_queue_stats stats;
154 u8 v_idx; /* maps directly to the index for this ring in the hardware
155 * vector array, can also be used for finding the bit in EICR
156 * and friends that represents the vector for this ring */
141 157
142 u32 eims_value; 158 u32 eims_value;
143 u16 itr_register; 159 u16 itr_register;
@@ -146,6 +162,33 @@ struct ixgbe_ring {
146 u16 work_limit; /* max work per interrupt */ 162 u16 work_limit; /* max work per interrupt */
147}; 163};
148 164
165#define RING_F_VMDQ 1
166#define RING_F_RSS 2
167#define IXGBE_MAX_RSS_INDICES 16
168#define IXGBE_MAX_VMDQ_INDICES 16
169struct ixgbe_ring_feature {
170 int indices;
171 int mask;
172};
173
174#define MAX_RX_QUEUES 64
175#define MAX_TX_QUEUES 32
176
177/* MAX_MSIX_Q_VECTORS of these are allocated,
178 * but we only use one per queue-specific vector.
179 */
180struct ixgbe_q_vector {
181 struct ixgbe_adapter *adapter;
182 struct napi_struct napi;
183 DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
184 DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
185 u8 rxr_count; /* Rx ring count assigned to this vector */
186 u8 txr_count; /* Tx ring count assigned to this vector */
187 u8 tx_eitr;
188 u8 rx_eitr;
189 u32 eitr;
190};
191
149/* Helper macros to switch between ints/sec and what the register uses. 192/* Helper macros to switch between ints/sec and what the register uses.
150 * And yes, it's the same math going both ways. 193 * And yes, it's the same math going both ways.
151 */ 194 */
@@ -166,6 +209,14 @@ struct ixgbe_ring {
166 209
167#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128 210#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
168 211
212#define OTHER_VECTOR 1
213#define NON_Q_VECTORS (OTHER_VECTOR)
214
215#define MAX_MSIX_Q_VECTORS 16
216#define MIN_MSIX_Q_VECTORS 2
217#define MAX_MSIX_COUNT (MAX_MSIX_Q_VECTORS + NON_Q_VECTORS)
218#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
219
169/* board specific private data structure */ 220/* board specific private data structure */
170struct ixgbe_adapter { 221struct ixgbe_adapter {
171 struct timer_list watchdog_timer; 222 struct timer_list watchdog_timer;
@@ -173,10 +224,16 @@ struct ixgbe_adapter {
173 u16 bd_number; 224 u16 bd_number;
174 u16 rx_buf_len; 225 u16 rx_buf_len;
175 struct work_struct reset_task; 226 struct work_struct reset_task;
227 struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
228 char name[MAX_MSIX_COUNT][IFNAMSIZ + 5];
229
230 /* Interrupt Throttle Rate */
231 u32 itr_setting;
232 u16 eitr_low;
233 u16 eitr_high;
176 234
177 /* TX */ 235 /* TX */
178 struct ixgbe_ring *tx_ring; /* One per active queue */ 236 struct ixgbe_ring *tx_ring; /* One per active queue */
179 struct napi_struct napi;
180 u64 restart_queue; 237 u64 restart_queue;
181 u64 lsc_int; 238 u64 lsc_int;
182 u64 hw_tso_ctxt; 239 u64 hw_tso_ctxt;
@@ -192,22 +249,27 @@ struct ixgbe_adapter {
192 u64 non_eop_descs; 249 u64 non_eop_descs;
193 int num_tx_queues; 250 int num_tx_queues;
194 int num_rx_queues; 251 int num_rx_queues;
252 int num_msix_vectors;
253 struct ixgbe_ring_feature ring_feature[3];
195 struct msix_entry *msix_entries; 254 struct msix_entry *msix_entries;
196 255
197 u64 rx_hdr_split; 256 u64 rx_hdr_split;
198 u32 alloc_rx_page_failed; 257 u32 alloc_rx_page_failed;
199 u32 alloc_rx_buff_failed; 258 u32 alloc_rx_buff_failed;
200 259
260 /* Some features need tri-state capability,
261 * thus the additional *_CAPABLE flags.
262 */
201 u32 flags; 263 u32 flags;
202#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1) 264#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1 << 0)
203#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 1) 265#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 1)
204#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 2) 266#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 2)
205#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 3) 267#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 3)
206#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 4) 268#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 4)
207 269#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 5)
208 /* Interrupt Throttle Rate */ 270#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 6)
209 u32 rx_eitr; 271#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 7)
210 u32 tx_eitr; 272#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 8)
211 273
212 /* OS defined structs */ 274 /* OS defined structs */
213 struct net_device *netdev; 275 struct net_device *netdev;
@@ -218,7 +280,10 @@ struct ixgbe_adapter {
218 struct ixgbe_hw hw; 280 struct ixgbe_hw hw;
219 u16 msg_enable; 281 u16 msg_enable;
220 struct ixgbe_hw_stats stats; 282 struct ixgbe_hw_stats stats;
221 char lsc_name[IFNAMSIZ + 5]; 283
284 /* Interrupt Throttle Rate */
285 u32 rx_eitr;
286 u32 tx_eitr;
222 287
223 unsigned long state; 288 unsigned long state;
224 u64 tx_busy; 289 u64 tx_busy;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index a119cbd8dbb8..4e463778bcfd 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -246,13 +246,26 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
246 246
247static int ixgbe_set_tso(struct net_device *netdev, u32 data) 247static int ixgbe_set_tso(struct net_device *netdev, u32 data)
248{ 248{
249
250 if (data) { 249 if (data) {
251 netdev->features |= NETIF_F_TSO; 250 netdev->features |= NETIF_F_TSO;
252 netdev->features |= NETIF_F_TSO6; 251 netdev->features |= NETIF_F_TSO6;
253 } else { 252 } else {
253#ifdef CONFIG_NETDEVICES_MULTIQUEUE
254 struct ixgbe_adapter *adapter = netdev_priv(netdev);
255 int i;
256#endif
257 netif_stop_queue(netdev);
258#ifdef CONFIG_NETDEVICES_MULTIQUEUE
259 for (i = 0; i < adapter->num_tx_queues; i++)
260 netif_stop_subqueue(netdev, i);
261#endif
254 netdev->features &= ~NETIF_F_TSO; 262 netdev->features &= ~NETIF_F_TSO;
255 netdev->features &= ~NETIF_F_TSO6; 263 netdev->features &= ~NETIF_F_TSO6;
264#ifdef CONFIG_NETDEVICES_MULTIQUEUE
265 for (i = 0; i < adapter->num_tx_queues; i++)
266 netif_start_subqueue(netdev, i);
267#endif
268 netif_start_queue(netdev);
256 } 269 }
257 return 0; 270 return 0;
258} 271}
@@ -873,13 +886,13 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
873{ 886{
874 struct ixgbe_adapter *adapter = netdev_priv(netdev); 887 struct ixgbe_adapter *adapter = netdev_priv(netdev);
875 888
876 if (adapter->rx_eitr == 0) 889 if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
877 ec->rx_coalesce_usecs = 0; 890 ec->rx_coalesce_usecs = adapter->rx_eitr;
878 else 891 else
879 ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr; 892 ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr;
880 893
881 if (adapter->tx_eitr == 0) 894 if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS)
882 ec->tx_coalesce_usecs = 0; 895 ec->tx_coalesce_usecs = adapter->tx_eitr;
883 else 896 else
884 ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr; 897 ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr;
885 898
@@ -893,22 +906,26 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
893 struct ixgbe_adapter *adapter = netdev_priv(netdev); 906 struct ixgbe_adapter *adapter = netdev_priv(netdev);
894 907
895 if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || 908 if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
896 ((ec->rx_coalesce_usecs > 0) && 909 ((ec->rx_coalesce_usecs != 0) &&
910 (ec->rx_coalesce_usecs != 1) &&
911 (ec->rx_coalesce_usecs != 3) &&
897 (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) 912 (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
898 return -EINVAL; 913 return -EINVAL;
899 if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || 914 if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
900 ((ec->tx_coalesce_usecs > 0) && 915 ((ec->tx_coalesce_usecs != 0) &&
916 (ec->tx_coalesce_usecs != 1) &&
917 (ec->tx_coalesce_usecs != 3) &&
901 (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) 918 (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
902 return -EINVAL; 919 return -EINVAL;
903 920
904 /* convert to rate of irq's per second */ 921 /* convert to rate of irq's per second */
905 if (ec->rx_coalesce_usecs == 0) 922 if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
906 adapter->rx_eitr = 0; 923 adapter->rx_eitr = ec->rx_coalesce_usecs;
907 else 924 else
908 adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs); 925 adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs);
909 926
910 if (ec->tx_coalesce_usecs == 0) 927 if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
911 adapter->tx_eitr = 0; 928 adapter->tx_eitr = ec->rx_coalesce_usecs;
912 else 929 else
913 adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs); 930 adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs);
914 931
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index c2095ce531c9..7ad2993dc581 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
48static const char ixgbe_driver_string[] = 48static const char ixgbe_driver_string[] =
49 "Intel(R) 10 Gigabit PCI Express Network Driver"; 49 "Intel(R) 10 Gigabit PCI Express Network Driver";
50 50
51#define DRV_VERSION "1.1.18" 51#define DRV_VERSION "1.3.18-k2"
52const char ixgbe_driver_version[] = DRV_VERSION; 52const char ixgbe_driver_version[] = DRV_VERSION;
53static const char ixgbe_copyright[] = 53static const char ixgbe_copyright[] =
54 "Copyright (c) 1999-2007 Intel Corporation."; 54 "Copyright (c) 1999-2007 Intel Corporation.";
@@ -80,6 +80,16 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
80}; 80};
81MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); 81MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
82 82
83#ifdef CONFIG_DCA
84static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
85 void *p);
86static struct notifier_block dca_notifier = {
87 .notifier_call = ixgbe_notify_dca,
88 .next = NULL,
89 .priority = 0
90};
91#endif
92
83MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); 93MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
84MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); 94MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
85MODULE_LICENSE("GPL"); 95MODULE_LICENSE("GPL");
@@ -256,26 +266,125 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
256 * sees the new next_to_clean. 266 * sees the new next_to_clean.
257 */ 267 */
258 smp_mb(); 268 smp_mb();
269#ifdef CONFIG_NETDEVICES_MULTIQUEUE
270 if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
271 !test_bit(__IXGBE_DOWN, &adapter->state)) {
272 netif_wake_subqueue(netdev, tx_ring->queue_index);
273 adapter->restart_queue++;
274 }
275#else
259 if (netif_queue_stopped(netdev) && 276 if (netif_queue_stopped(netdev) &&
260 !test_bit(__IXGBE_DOWN, &adapter->state)) { 277 !test_bit(__IXGBE_DOWN, &adapter->state)) {
261 netif_wake_queue(netdev); 278 netif_wake_queue(netdev);
262 adapter->restart_queue++; 279 adapter->restart_queue++;
263 } 280 }
281#endif
264 } 282 }
265 283
266 if (adapter->detect_tx_hung) 284 if (adapter->detect_tx_hung)
267 if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc)) 285 if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc))
286#ifdef CONFIG_NETDEVICES_MULTIQUEUE
287 netif_stop_subqueue(netdev, tx_ring->queue_index);
288#else
268 netif_stop_queue(netdev); 289 netif_stop_queue(netdev);
290#endif
269 291
270 if (total_tx_packets >= tx_ring->work_limit) 292 if (total_tx_packets >= tx_ring->work_limit)
271 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value); 293 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value);
272 294
295 tx_ring->total_bytes += total_tx_bytes;
296 tx_ring->total_packets += total_tx_packets;
273 adapter->net_stats.tx_bytes += total_tx_bytes; 297 adapter->net_stats.tx_bytes += total_tx_bytes;
274 adapter->net_stats.tx_packets += total_tx_packets; 298 adapter->net_stats.tx_packets += total_tx_packets;
275 cleaned = total_tx_packets ? true : false; 299 cleaned = total_tx_packets ? true : false;
276 return cleaned; 300 return cleaned;
277} 301}
278 302
303#ifdef CONFIG_DCA
304static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
305 struct ixgbe_ring *rxr)
306{
307 u32 rxctrl;
308 int cpu = get_cpu();
309 int q = rxr - adapter->rx_ring;
310
311 if (rxr->cpu != cpu) {
312 rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
313 rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
314 rxctrl |= dca_get_tag(cpu);
315 rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
316 rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
317 IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
318 rxr->cpu = cpu;
319 }
320 put_cpu();
321}
322
323static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
324 struct ixgbe_ring *txr)
325{
326 u32 txctrl;
327 int cpu = get_cpu();
328 int q = txr - adapter->tx_ring;
329
330 if (txr->cpu != cpu) {
331 txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
332 txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
333 txctrl |= dca_get_tag(cpu);
334 txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
335 IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
336 txr->cpu = cpu;
337 }
338 put_cpu();
339}
340
341static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
342{
343 int i;
344
345 if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
346 return;
347
348 for (i = 0; i < adapter->num_tx_queues; i++) {
349 adapter->tx_ring[i].cpu = -1;
350 ixgbe_update_tx_dca(adapter, &adapter->tx_ring[i]);
351 }
352 for (i = 0; i < adapter->num_rx_queues; i++) {
353 adapter->rx_ring[i].cpu = -1;
354 ixgbe_update_rx_dca(adapter, &adapter->rx_ring[i]);
355 }
356}
357
358static int __ixgbe_notify_dca(struct device *dev, void *data)
359{
360 struct net_device *netdev = dev_get_drvdata(dev);
361 struct ixgbe_adapter *adapter = netdev_priv(netdev);
362 unsigned long event = *(unsigned long *)data;
363
364 switch (event) {
365 case DCA_PROVIDER_ADD:
366 adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
367 /* Always use CB2 mode, difference is masked
368 * in the CB driver. */
369 IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
370 if (dca_add_requester(dev) == IXGBE_SUCCESS) {
371 ixgbe_setup_dca(adapter);
372 break;
373 }
374 /* Fall Through since DCA is disabled. */
375 case DCA_PROVIDER_REMOVE:
376 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
377 dca_remove_requester(dev);
378 adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
379 IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 1);
380 }
381 break;
382 }
383
384 return IXGBE_SUCCESS;
385}
386
387#endif /* CONFIG_DCA */
279/** 388/**
280 * ixgbe_receive_skb - Send a completed packet up the stack 389 * ixgbe_receive_skb - Send a completed packet up the stack
281 * @adapter: board private structure 390 * @adapter: board private structure
@@ -556,10 +665,15 @@ next_desc:
556 adapter->net_stats.rx_bytes += total_rx_bytes; 665 adapter->net_stats.rx_bytes += total_rx_bytes;
557 adapter->net_stats.rx_packets += total_rx_packets; 666 adapter->net_stats.rx_packets += total_rx_packets;
558 667
668 rx_ring->total_packets += total_rx_packets;
669 rx_ring->total_bytes += total_rx_bytes;
670 adapter->net_stats.rx_bytes += total_rx_bytes;
671 adapter->net_stats.rx_packets += total_rx_packets;
672
559 return cleaned; 673 return cleaned;
560} 674}
561 675
562#define IXGBE_MAX_INTR 10 676static int ixgbe_clean_rxonly(struct napi_struct *, int);
563/** 677/**
564 * ixgbe_configure_msix - Configure MSI-X hardware 678 * ixgbe_configure_msix - Configure MSI-X hardware
565 * @adapter: board private structure 679 * @adapter: board private structure
@@ -569,28 +683,195 @@ next_desc:
569 **/ 683 **/
570static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) 684static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
571{ 685{
572 int i, vector = 0; 686 struct ixgbe_q_vector *q_vector;
687 int i, j, q_vectors, v_idx, r_idx;
688 u32 mask;
573 689
574 for (i = 0; i < adapter->num_tx_queues; i++) { 690 q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
575 ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(i),
576 IXGBE_MSIX_VECTOR(vector));
577 writel(EITR_INTS_PER_SEC_TO_REG(adapter->tx_eitr),
578 adapter->hw.hw_addr + adapter->tx_ring[i].itr_register);
579 vector++;
580 }
581 691
582 for (i = 0; i < adapter->num_rx_queues; i++) { 692 /* Populate the IVAR table and set the ITR values to the
583 ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(i), 693 * corresponding register.
584 IXGBE_MSIX_VECTOR(vector)); 694 */
585 writel(EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr), 695 for (v_idx = 0; v_idx < q_vectors; v_idx++) {
586 adapter->hw.hw_addr + adapter->rx_ring[i].itr_register); 696 q_vector = &adapter->q_vector[v_idx];
587 vector++; 697 /* XXX for_each_bit(...) */
698 r_idx = find_first_bit(q_vector->rxr_idx,
699 adapter->num_rx_queues);
700
701 for (i = 0; i < q_vector->rxr_count; i++) {
702 j = adapter->rx_ring[r_idx].reg_idx;
703 ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx);
704 r_idx = find_next_bit(q_vector->rxr_idx,
705 adapter->num_rx_queues,
706 r_idx + 1);
707 }
708 r_idx = find_first_bit(q_vector->txr_idx,
709 adapter->num_tx_queues);
710
711 for (i = 0; i < q_vector->txr_count; i++) {
712 j = adapter->tx_ring[r_idx].reg_idx;
713 ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx);
714 r_idx = find_next_bit(q_vector->txr_idx,
715 adapter->num_tx_queues,
716 r_idx + 1);
717 }
718
719 /* if this is a tx only vector use half the irq (tx) rate */
720 if (q_vector->txr_count && !q_vector->rxr_count)
721 q_vector->eitr = adapter->tx_eitr;
722 else
723 /* rx only or mixed */
724 q_vector->eitr = adapter->rx_eitr;
725
726 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
727 EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
588 } 728 }
589 729
590 vector = adapter->num_tx_queues + adapter->num_rx_queues; 730 ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx);
591 ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, 731 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
592 IXGBE_MSIX_VECTOR(vector)); 732
593 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(vector), 1950); 733 /* set up to autoclear timer, lsc, and the vectors */
734 mask = IXGBE_EIMS_ENABLE_MASK;
735 mask &= ~IXGBE_EIMS_OTHER;
736 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask);
737}
738
739enum latency_range {
740 lowest_latency = 0,
741 low_latency = 1,
742 bulk_latency = 2,
743 latency_invalid = 255
744};
745
746/**
747 * ixgbe_update_itr - update the dynamic ITR value based on statistics
748 * @adapter: pointer to adapter
749 * @eitr: eitr setting (ints per sec) to give last timeslice
750 * @itr_setting: current throttle rate in ints/second
751 * @packets: the number of packets during this measurement interval
752 * @bytes: the number of bytes during this measurement interval
753 *
754 * Stores a new ITR value based on packets and byte
755 * counts during the last interrupt. The advantage of per interrupt
756 * computation is faster updates and more accurate ITR for the current
757 * traffic pattern. Constants in this function were computed
758 * based on theoretical maximum wire speed and thresholds were set based
759 * on testing data as well as attempting to minimize response time
760 * while increasing bulk throughput.
761 * this functionality is controlled by the InterruptThrottleRate module
762 * parameter (see ixgbe_param.c)
763 **/
764static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter,
765 u32 eitr, u8 itr_setting,
766 int packets, int bytes)
767{
768 unsigned int retval = itr_setting;
769 u32 timepassed_us;
770 u64 bytes_perint;
771
772 if (packets == 0)
773 goto update_itr_done;
774
775
776 /* simple throttlerate management
777 * 0-20MB/s lowest (100000 ints/s)
778 * 20-100MB/s low (20000 ints/s)
779 * 100-1249MB/s bulk (8000 ints/s)
780 */
781 /* what was last interrupt timeslice? */
782 timepassed_us = 1000000/eitr;
783 bytes_perint = bytes / timepassed_us; /* bytes/usec */
784
785 switch (itr_setting) {
786 case lowest_latency:
787 if (bytes_perint > adapter->eitr_low)
788 retval = low_latency;
789 break;
790 case low_latency:
791 if (bytes_perint > adapter->eitr_high)
792 retval = bulk_latency;
793 else if (bytes_perint <= adapter->eitr_low)
794 retval = lowest_latency;
795 break;
796 case bulk_latency:
797 if (bytes_perint <= adapter->eitr_high)
798 retval = low_latency;
799 break;
800 }
801
802update_itr_done:
803 return retval;
804}
805
806static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
807{
808 struct ixgbe_adapter *adapter = q_vector->adapter;
809 struct ixgbe_hw *hw = &adapter->hw;
810 u32 new_itr;
811 u8 current_itr, ret_itr;
812 int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
813 sizeof(struct ixgbe_q_vector);
814 struct ixgbe_ring *rx_ring, *tx_ring;
815
816 r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
817 for (i = 0; i < q_vector->txr_count; i++) {
818 tx_ring = &(adapter->tx_ring[r_idx]);
819 ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
820 q_vector->tx_eitr,
821 tx_ring->total_packets,
822 tx_ring->total_bytes);
823 /* if the result for this queue would decrease interrupt
824 * rate for this vector then use that result */
825 q_vector->tx_eitr = ((q_vector->tx_eitr > ret_itr) ?
826 q_vector->tx_eitr - 1 : ret_itr);
827 r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
828 r_idx + 1);
829 }
830
831 r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
832 for (i = 0; i < q_vector->rxr_count; i++) {
833 rx_ring = &(adapter->rx_ring[r_idx]);
834 ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
835 q_vector->rx_eitr,
836 rx_ring->total_packets,
837 rx_ring->total_bytes);
838 /* if the result for this queue would decrease interrupt
839 * rate for this vector then use that result */
840 q_vector->rx_eitr = ((q_vector->rx_eitr > ret_itr) ?
841 q_vector->rx_eitr - 1 : ret_itr);
842 r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
843 r_idx + 1);
844 }
845
846 current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
847
848 switch (current_itr) {
849 /* counts and packets in update_itr are dependent on these numbers */
850 case lowest_latency:
851 new_itr = 100000;
852 break;
853 case low_latency:
854 new_itr = 20000; /* aka hwitr = ~200 */
855 break;
856 case bulk_latency:
857 default:
858 new_itr = 8000;
859 break;
860 }
861
862 if (new_itr != q_vector->eitr) {
863 u32 itr_reg;
864 /* do an exponential smoothing */
865 new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
866 q_vector->eitr = new_itr;
867 itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
868 /* must write high and low 16 bits to reset counter */
869 DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
870 itr_reg);
871 IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
872 }
873
874 return;
594} 875}
595 876
596static irqreturn_t ixgbe_msix_lsc(int irq, void *data) 877static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
@@ -614,153 +895,302 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
614 895
615static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) 896static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
616{ 897{
617 struct ixgbe_ring *txr = data; 898 struct ixgbe_q_vector *q_vector = data;
618 struct ixgbe_adapter *adapter = txr->adapter; 899 struct ixgbe_adapter *adapter = q_vector->adapter;
900 struct ixgbe_ring *txr;
901 int i, r_idx;
619 902
620 ixgbe_clean_tx_irq(adapter, txr); 903 if (!q_vector->txr_count)
904 return IRQ_HANDLED;
905
906 r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
907 for (i = 0; i < q_vector->txr_count; i++) {
908 txr = &(adapter->tx_ring[r_idx]);
909#ifdef CONFIG_DCA
910 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
911 ixgbe_update_tx_dca(adapter, txr);
912#endif
913 txr->total_bytes = 0;
914 txr->total_packets = 0;
915 ixgbe_clean_tx_irq(adapter, txr);
916 r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
917 r_idx + 1);
918 }
621 919
622 return IRQ_HANDLED; 920 return IRQ_HANDLED;
623} 921}
624 922
923/**
924 * ixgbe_msix_clean_rx - single unshared vector rx clean (all queues)
925 * @irq: unused
926 * @data: pointer to our q_vector struct for this interrupt vector
927 **/
625static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) 928static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
626{ 929{
627 struct ixgbe_ring *rxr = data; 930 struct ixgbe_q_vector *q_vector = data;
628 struct ixgbe_adapter *adapter = rxr->adapter; 931 struct ixgbe_adapter *adapter = q_vector->adapter;
932 struct ixgbe_ring *rxr;
933 int r_idx;
934
935 r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
936 if (!q_vector->rxr_count)
937 return IRQ_HANDLED;
938
939 rxr = &(adapter->rx_ring[r_idx]);
940 /* disable interrupts on this vector only */
941 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rxr->v_idx);
942 rxr->total_bytes = 0;
943 rxr->total_packets = 0;
944 netif_rx_schedule(adapter->netdev, &q_vector->napi);
945
946 return IRQ_HANDLED;
947}
948
949static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
950{
951 ixgbe_msix_clean_rx(irq, data);
952 ixgbe_msix_clean_tx(irq, data);
629 953
630 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rxr->eims_value);
631 netif_rx_schedule(adapter->netdev, &adapter->napi);
632 return IRQ_HANDLED; 954 return IRQ_HANDLED;
633} 955}
634 956
957/**
958 * ixgbe_clean_rxonly - msix (aka one shot) rx clean routine
959 * @napi: napi struct with our devices info in it
960 * @budget: amount of work driver is allowed to do this pass, in packets
961 *
962 **/
635static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) 963static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
636{ 964{
637 struct ixgbe_adapter *adapter = container_of(napi, 965 struct ixgbe_q_vector *q_vector =
638 struct ixgbe_adapter, napi); 966 container_of(napi, struct ixgbe_q_vector, napi);
639 struct net_device *netdev = adapter->netdev; 967 struct ixgbe_adapter *adapter = q_vector->adapter;
968 struct ixgbe_ring *rxr;
640 int work_done = 0; 969 int work_done = 0;
641 struct ixgbe_ring *rxr = adapter->rx_ring; 970 long r_idx;
642 971
643 /* Keep link state information with original netdev */ 972 r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
644 if (!netif_carrier_ok(netdev)) 973 rxr = &(adapter->rx_ring[r_idx]);
645 goto quit_polling; 974#ifdef CONFIG_DCA
975 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
976 ixgbe_update_rx_dca(adapter, rxr);
977#endif
646 978
647 ixgbe_clean_rx_irq(adapter, rxr, &work_done, budget); 979 ixgbe_clean_rx_irq(adapter, rxr, &work_done, budget);
648 980
649 /* If no Tx and not enough Rx work done, exit the polling mode */ 981 /* If all Rx work done, exit the polling mode */
650 if ((work_done < budget) || !netif_running(netdev)) { 982 if (work_done < budget) {
651quit_polling: 983 netif_rx_complete(adapter->netdev, napi);
652 netif_rx_complete(netdev, napi); 984 if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
985 ixgbe_set_itr_msix(q_vector);
653 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 986 if (!test_bit(__IXGBE_DOWN, &adapter->state))
654 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, 987 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rxr->v_idx);
655 rxr->eims_value);
656 } 988 }
657 989
658 return work_done; 990 return work_done;
659} 991}
660 992
993static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
994 int r_idx)
995{
996 a->q_vector[v_idx].adapter = a;
997 set_bit(r_idx, a->q_vector[v_idx].rxr_idx);
998 a->q_vector[v_idx].rxr_count++;
999 a->rx_ring[r_idx].v_idx = 1 << v_idx;
1000}
1001
1002static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
1003 int r_idx)
1004{
1005 a->q_vector[v_idx].adapter = a;
1006 set_bit(r_idx, a->q_vector[v_idx].txr_idx);
1007 a->q_vector[v_idx].txr_count++;
1008 a->tx_ring[r_idx].v_idx = 1 << v_idx;
1009}
1010
661/** 1011/**
662 * ixgbe_setup_msix - Initialize MSI-X interrupts 1012 * ixgbe_map_rings_to_vectors - Maps descriptor rings to vectors
1013 * @adapter: board private structure to initialize
1014 * @vectors: allotted vector count for descriptor rings
663 * 1015 *
664 * ixgbe_setup_msix allocates MSI-X vectors and requests 1016 * This function maps descriptor rings to the queue-specific vectors
665 * interrutps from the kernel. 1017 * we were allotted through the MSI-X enabling code. Ideally, we'd have
1018 * one vector per ring/queue, but on a constrained vector budget, we
1019 * group the rings as "efficiently" as possible. You would add new
1020 * mapping configurations in here.
666 **/ 1021 **/
667static int ixgbe_setup_msix(struct ixgbe_adapter *adapter) 1022static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
668{ 1023 int vectors)
669 struct net_device *netdev = adapter->netdev; 1024{
670 int i, int_vector = 0, err = 0; 1025 int v_start = 0;
671 int max_msix_count; 1026 int rxr_idx = 0, txr_idx = 0;
1027 int rxr_remaining = adapter->num_rx_queues;
1028 int txr_remaining = adapter->num_tx_queues;
1029 int i, j;
1030 int rqpv, tqpv;
1031 int err = 0;
1032
1033 /* No mapping required if MSI-X is disabled. */
1034 if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
1035 goto out;
672 1036
673 /* +1 for the LSC interrupt */ 1037 /*
674 max_msix_count = adapter->num_rx_queues + adapter->num_tx_queues + 1; 1038 * The ideal configuration...
675 adapter->msix_entries = kcalloc(max_msix_count, 1039 * We have enough vectors to map one per queue.
676 sizeof(struct msix_entry), GFP_KERNEL); 1040 */
677 if (!adapter->msix_entries) 1041 if (vectors == adapter->num_rx_queues + adapter->num_tx_queues) {
678 return -ENOMEM; 1042 for (; rxr_idx < rxr_remaining; v_start++, rxr_idx++)
1043 map_vector_to_rxq(adapter, v_start, rxr_idx);
679 1044
680 for (i = 0; i < max_msix_count; i++) 1045 for (; txr_idx < txr_remaining; v_start++, txr_idx++)
681 adapter->msix_entries[i].entry = i; 1046 map_vector_to_txq(adapter, v_start, txr_idx);
682 1047
683 err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
684 max_msix_count);
685 if (err)
686 goto out; 1048 goto out;
1049 }
687 1050
688 for (i = 0; i < adapter->num_tx_queues; i++) { 1051 /*
689 sprintf(adapter->tx_ring[i].name, "%s-tx%d", netdev->name, i); 1052 * If we don't have enough vectors for a 1-to-1
690 err = request_irq(adapter->msix_entries[int_vector].vector, 1053 * mapping, we'll have to group them so there are
691 &ixgbe_msix_clean_tx, 1054 * multiple queues per vector.
692 0, 1055 */
693 adapter->tx_ring[i].name, 1056 /* Re-adjusting *qpv takes care of the remainder. */
694 &(adapter->tx_ring[i])); 1057 for (i = v_start; i < vectors; i++) {
695 if (err) { 1058 rqpv = DIV_ROUND_UP(rxr_remaining, vectors - i);
696 DPRINTK(PROBE, ERR, 1059 for (j = 0; j < rqpv; j++) {
697 "request_irq failed for MSIX interrupt " 1060 map_vector_to_rxq(adapter, i, rxr_idx);
698 "Error: %d\n", err); 1061 rxr_idx++;
699 goto release_irqs; 1062 rxr_remaining--;
1063 }
1064 }
1065 for (i = v_start; i < vectors; i++) {
1066 tqpv = DIV_ROUND_UP(txr_remaining, vectors - i);
1067 for (j = 0; j < tqpv; j++) {
1068 map_vector_to_txq(adapter, i, txr_idx);
1069 txr_idx++;
1070 txr_remaining--;
700 } 1071 }
701 adapter->tx_ring[i].eims_value =
702 (1 << IXGBE_MSIX_VECTOR(int_vector));
703 adapter->tx_ring[i].itr_register = IXGBE_EITR(int_vector);
704 int_vector++;
705 } 1072 }
706 1073
707 for (i = 0; i < adapter->num_rx_queues; i++) { 1074out:
708 if (strlen(netdev->name) < (IFNAMSIZ - 5)) 1075 return err;
709 sprintf(adapter->rx_ring[i].name, 1076}
710 "%s-rx%d", netdev->name, i); 1077
711 else 1078/**
712 memcpy(adapter->rx_ring[i].name, 1079 * ixgbe_request_msix_irqs - Initialize MSI-X interrupts
713 netdev->name, IFNAMSIZ); 1080 * @adapter: board private structure
714 err = request_irq(adapter->msix_entries[int_vector].vector, 1081 *
715 &ixgbe_msix_clean_rx, 0, 1082 * ixgbe_request_msix_irqs allocates MSI-X vectors and requests
716 adapter->rx_ring[i].name, 1083 * interrupts from the kernel.
717 &(adapter->rx_ring[i])); 1084 **/
1085static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
1086{
1087 struct net_device *netdev = adapter->netdev;
1088 irqreturn_t (*handler)(int, void *);
1089 int i, vector, q_vectors, err;
1090
1091 /* Decrement for Other and TCP Timer vectors */
1092 q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
1093
1094 /* Map the Tx/Rx rings to the vectors we were allotted. */
1095 err = ixgbe_map_rings_to_vectors(adapter, q_vectors);
1096 if (err)
1097 goto out;
1098
1099#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \
1100 (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
1101 &ixgbe_msix_clean_many)
1102 for (vector = 0; vector < q_vectors; vector++) {
1103 handler = SET_HANDLER(&adapter->q_vector[vector]);
1104 sprintf(adapter->name[vector], "%s:v%d-%s",
1105 netdev->name, vector,
1106 (handler == &ixgbe_msix_clean_rx) ? "Rx" :
1107 ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx"));
1108 err = request_irq(adapter->msix_entries[vector].vector,
1109 handler, 0, adapter->name[vector],
1110 &(adapter->q_vector[vector]));
718 if (err) { 1111 if (err) {
719 DPRINTK(PROBE, ERR, 1112 DPRINTK(PROBE, ERR,
720 "request_irq failed for MSIX interrupt " 1113 "request_irq failed for MSIX interrupt "
721 "Error: %d\n", err); 1114 "Error: %d\n", err);
722 goto release_irqs; 1115 goto free_queue_irqs;
723 } 1116 }
724
725 adapter->rx_ring[i].eims_value =
726 (1 << IXGBE_MSIX_VECTOR(int_vector));
727 adapter->rx_ring[i].itr_register = IXGBE_EITR(int_vector);
728 int_vector++;
729 } 1117 }
730 1118
731 sprintf(adapter->lsc_name, "%s-lsc", netdev->name); 1119 sprintf(adapter->name[vector], "%s:lsc", netdev->name);
732 err = request_irq(adapter->msix_entries[int_vector].vector, 1120 err = request_irq(adapter->msix_entries[vector].vector,
733 &ixgbe_msix_lsc, 0, adapter->lsc_name, netdev); 1121 &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
734 if (err) { 1122 if (err) {
735 DPRINTK(PROBE, ERR, 1123 DPRINTK(PROBE, ERR,
736 "request_irq for msix_lsc failed: %d\n", err); 1124 "request_irq for msix_lsc failed: %d\n", err);
737 goto release_irqs; 1125 goto free_queue_irqs;
738 } 1126 }
739 1127
740 /* FIXME: implement netif_napi_remove() instead */
741 adapter->napi.poll = ixgbe_clean_rxonly;
742 adapter->flags |= IXGBE_FLAG_MSIX_ENABLED;
743 return 0; 1128 return 0;
744 1129
745release_irqs: 1130free_queue_irqs:
746 int_vector--; 1131 for (i = vector - 1; i >= 0; i--)
747 for (; int_vector >= adapter->num_tx_queues; int_vector--) 1132 free_irq(adapter->msix_entries[--vector].vector,
748 free_irq(adapter->msix_entries[int_vector].vector, 1133 &(adapter->q_vector[i]));
749 &(adapter->rx_ring[int_vector - 1134 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
750 adapter->num_tx_queues])); 1135 pci_disable_msix(adapter->pdev);
751
752 for (; int_vector >= 0; int_vector--)
753 free_irq(adapter->msix_entries[int_vector].vector,
754 &(adapter->tx_ring[int_vector]));
755out:
756 kfree(adapter->msix_entries); 1136 kfree(adapter->msix_entries);
757 adapter->msix_entries = NULL; 1137 adapter->msix_entries = NULL;
758 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; 1138out:
759 return err; 1139 return err;
760} 1140}
761 1141
1142static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
1143{
1144 struct ixgbe_hw *hw = &adapter->hw;
1145 struct ixgbe_q_vector *q_vector = adapter->q_vector;
1146 u8 current_itr;
1147 u32 new_itr = q_vector->eitr;
1148 struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
1149 struct ixgbe_ring *tx_ring = &adapter->tx_ring[0];
1150
1151 q_vector->tx_eitr = ixgbe_update_itr(adapter, new_itr,
1152 q_vector->tx_eitr,
1153 tx_ring->total_packets,
1154 tx_ring->total_bytes);
1155 q_vector->rx_eitr = ixgbe_update_itr(adapter, new_itr,
1156 q_vector->rx_eitr,
1157 rx_ring->total_packets,
1158 rx_ring->total_bytes);
1159
1160 current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
1161
1162 switch (current_itr) {
1163 /* counts and packets in update_itr are dependent on these numbers */
1164 case lowest_latency:
1165 new_itr = 100000;
1166 break;
1167 case low_latency:
1168 new_itr = 20000; /* aka hwitr = ~200 */
1169 break;
1170 case bulk_latency:
1171 new_itr = 8000;
1172 break;
1173 default:
1174 break;
1175 }
1176
1177 if (new_itr != q_vector->eitr) {
1178 u32 itr_reg;
1179 /* do an exponential smoothing */
1180 new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
1181 q_vector->eitr = new_itr;
1182 itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
1183 /* must write high and low 16 bits to reset counter */
1184 IXGBE_WRITE_REG(hw, IXGBE_EITR(0), itr_reg | (itr_reg)<<16);
1185 }
1186
1187 return;
1188}
1189
1190static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter);
1191
762/** 1192/**
763 * ixgbe_intr - Interrupt Handler 1193 * ixgbe_intr - legacy mode Interrupt Handler
764 * @irq: interrupt number 1194 * @irq: interrupt number
765 * @data: pointer to a network interface device structure 1195 * @data: pointer to a network interface device structure
766 * @pt_regs: CPU registers structure 1196 * @pt_regs: CPU registers structure
@@ -772,8 +1202,10 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
772 struct ixgbe_hw *hw = &adapter->hw; 1202 struct ixgbe_hw *hw = &adapter->hw;
773 u32 eicr; 1203 u32 eicr;
774 1204
775 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
776 1205
1206 /* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read
1207 * therefore no explict interrupt disable is necessary */
1208 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
777 if (!eicr) 1209 if (!eicr)
778 return IRQ_NONE; /* Not our interrupt */ 1210 return IRQ_NONE; /* Not our interrupt */
779 1211
@@ -782,16 +1214,33 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
782 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 1214 if (!test_bit(__IXGBE_DOWN, &adapter->state))
783 mod_timer(&adapter->watchdog_timer, jiffies); 1215 mod_timer(&adapter->watchdog_timer, jiffies);
784 } 1216 }
785 if (netif_rx_schedule_prep(netdev, &adapter->napi)) { 1217
786 /* Disable interrupts and register for poll. The flush of the 1218
787 * posted write is intentionally left out. */ 1219 if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
788 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); 1220 adapter->tx_ring[0].total_packets = 0;
789 __netif_rx_schedule(netdev, &adapter->napi); 1221 adapter->tx_ring[0].total_bytes = 0;
1222 adapter->rx_ring[0].total_packets = 0;
1223 adapter->rx_ring[0].total_bytes = 0;
1224 /* would disable interrupts here but EIAM disabled it */
1225 __netif_rx_schedule(netdev, &adapter->q_vector[0].napi);
790 } 1226 }
791 1227
792 return IRQ_HANDLED; 1228 return IRQ_HANDLED;
793} 1229}
794 1230
1231static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter)
1232{
1233 int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
1234
1235 for (i = 0; i < q_vectors; i++) {
1236 struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
1237 bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
1238 bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
1239 q_vector->rxr_count = 0;
1240 q_vector->txr_count = 0;
1241 }
1242}
1243
795/** 1244/**
796 * ixgbe_request_irq - initialize interrupts 1245 * ixgbe_request_irq - initialize interrupts
797 * @adapter: board private structure 1246 * @adapter: board private structure
@@ -799,40 +1248,24 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
799 * Attempts to configure interrupts using the best available 1248 * Attempts to configure interrupts using the best available
800 * capabilities of the hardware and kernel. 1249 * capabilities of the hardware and kernel.
801 **/ 1250 **/
802static int ixgbe_request_irq(struct ixgbe_adapter *adapter, u32 *num_rx_queues) 1251static int ixgbe_request_irq(struct ixgbe_adapter *adapter)
803{ 1252{
804 struct net_device *netdev = adapter->netdev; 1253 struct net_device *netdev = adapter->netdev;
805 int flags, err; 1254 int err;
806 irq_handler_t handler = ixgbe_intr;
807
808 flags = IRQF_SHARED;
809
810 err = ixgbe_setup_msix(adapter);
811 if (!err)
812 goto request_done;
813
814 /*
815 * if we can't do MSI-X, fall through and try MSI
816 * No need to reallocate memory since we're decreasing the number of
817 * queues. We just won't use the other ones, also it is freed correctly
818 * on ixgbe_remove.
819 */
820 *num_rx_queues = 1;
821 1255
822 /* do MSI */ 1256 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
823 err = pci_enable_msi(adapter->pdev); 1257 err = ixgbe_request_msix_irqs(adapter);
824 if (!err) { 1258 } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
825 adapter->flags |= IXGBE_FLAG_MSI_ENABLED; 1259 err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0,
826 flags &= ~IRQF_SHARED; 1260 netdev->name, netdev);
827 handler = &ixgbe_intr; 1261 } else {
1262 err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED,
1263 netdev->name, netdev);
828 } 1264 }
829 1265
830 err = request_irq(adapter->pdev->irq, handler, flags,
831 netdev->name, netdev);
832 if (err) 1266 if (err)
833 DPRINTK(PROBE, ERR, "request_irq failed, Error %d\n", err); 1267 DPRINTK(PROBE, ERR, "request_irq failed, Error %d\n", err);
834 1268
835request_done:
836 return err; 1269 return err;
837} 1270}
838 1271
@@ -841,28 +1274,22 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
841 struct net_device *netdev = adapter->netdev; 1274 struct net_device *netdev = adapter->netdev;
842 1275
843 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { 1276 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
844 int i; 1277 int i, q_vectors;
845 1278
846 for (i = 0; i < adapter->num_tx_queues; i++) 1279 q_vectors = adapter->num_msix_vectors;
847 free_irq(adapter->msix_entries[i].vector, 1280
848 &(adapter->tx_ring[i])); 1281 i = q_vectors - 1;
849 for (i = 0; i < adapter->num_rx_queues; i++)
850 free_irq(adapter->msix_entries[i +
851 adapter->num_tx_queues].vector,
852 &(adapter->rx_ring[i]));
853 i = adapter->num_rx_queues + adapter->num_tx_queues;
854 free_irq(adapter->msix_entries[i].vector, netdev); 1282 free_irq(adapter->msix_entries[i].vector, netdev);
855 pci_disable_msix(adapter->pdev);
856 kfree(adapter->msix_entries);
857 adapter->msix_entries = NULL;
858 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
859 return;
860 }
861 1283
862 free_irq(adapter->pdev->irq, netdev); 1284 i--;
863 if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { 1285 for (; i >= 0; i--) {
864 pci_disable_msi(adapter->pdev); 1286 free_irq(adapter->msix_entries[i].vector,
865 adapter->flags &= ~IXGBE_FLAG_MSI_ENABLED; 1287 &(adapter->q_vector[i]));
1288 }
1289
1290 ixgbe_reset_q_vectors(adapter);
1291 } else {
1292 free_irq(adapter->pdev->irq, netdev);
866 } 1293 }
867} 1294}
868 1295
@@ -874,7 +1301,13 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
874{ 1301{
875 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); 1302 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
876 IXGBE_WRITE_FLUSH(&adapter->hw); 1303 IXGBE_WRITE_FLUSH(&adapter->hw);
877 synchronize_irq(adapter->pdev->irq); 1304 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
1305 int i;
1306 for (i = 0; i < adapter->num_msix_vectors; i++)
1307 synchronize_irq(adapter->msix_entries[i].vector);
1308 } else {
1309 synchronize_irq(adapter->pdev->irq);
1310 }
878} 1311}
879 1312
880/** 1313/**
@@ -883,12 +1316,9 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
883 **/ 1316 **/
884static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) 1317static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
885{ 1318{
886 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) 1319 u32 mask;
887 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, 1320 mask = IXGBE_EIMS_ENABLE_MASK;
888 (IXGBE_EIMS_ENABLE_MASK & 1321 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
889 ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC)));
890 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS,
891 IXGBE_EIMS_ENABLE_MASK);
892 IXGBE_WRITE_FLUSH(&adapter->hw); 1322 IXGBE_WRITE_FLUSH(&adapter->hw);
893} 1323}
894 1324
@@ -898,20 +1328,18 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
898 **/ 1328 **/
899static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) 1329static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
900{ 1330{
901 int i;
902 struct ixgbe_hw *hw = &adapter->hw; 1331 struct ixgbe_hw *hw = &adapter->hw;
903 1332
904 if (adapter->rx_eitr) 1333 IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
905 IXGBE_WRITE_REG(hw, IXGBE_EITR(0), 1334 EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr));
906 EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr));
907
908 /* for re-triggering the interrupt in non-NAPI mode */
909 adapter->rx_ring[0].eims_value = (1 << IXGBE_MSIX_VECTOR(0));
910 adapter->tx_ring[0].eims_value = (1 << IXGBE_MSIX_VECTOR(0));
911 1335
912 ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0); 1336 ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0);
913 for (i = 0; i < adapter->num_tx_queues; i++) 1337 ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0);
914 ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(i), i); 1338
1339 map_vector_to_rxq(adapter, 0, 0);
1340 map_vector_to_txq(adapter, 0, 0);
1341
1342 DPRINTK(HW, INFO, "Legacy interrupt IVAR setup done\n");
915} 1343}
916 1344
917/** 1345/**
@@ -924,23 +1352,29 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
924{ 1352{
925 u64 tdba; 1353 u64 tdba;
926 struct ixgbe_hw *hw = &adapter->hw; 1354 struct ixgbe_hw *hw = &adapter->hw;
927 u32 i, tdlen; 1355 u32 i, j, tdlen, txctrl;
928 1356
929 /* Setup the HW Tx Head and Tail descriptor pointers */ 1357 /* Setup the HW Tx Head and Tail descriptor pointers */
930 for (i = 0; i < adapter->num_tx_queues; i++) { 1358 for (i = 0; i < adapter->num_tx_queues; i++) {
1359 j = adapter->tx_ring[i].reg_idx;
931 tdba = adapter->tx_ring[i].dma; 1360 tdba = adapter->tx_ring[i].dma;
932 tdlen = adapter->tx_ring[i].count * 1361 tdlen = adapter->tx_ring[i].count *
933 sizeof(union ixgbe_adv_tx_desc); 1362 sizeof(union ixgbe_adv_tx_desc);
934 IXGBE_WRITE_REG(hw, IXGBE_TDBAL(i), (tdba & DMA_32BIT_MASK)); 1363 IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
935 IXGBE_WRITE_REG(hw, IXGBE_TDBAH(i), (tdba >> 32)); 1364 (tdba & DMA_32BIT_MASK));
936 IXGBE_WRITE_REG(hw, IXGBE_TDLEN(i), tdlen); 1365 IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
937 IXGBE_WRITE_REG(hw, IXGBE_TDH(i), 0); 1366 IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
938 IXGBE_WRITE_REG(hw, IXGBE_TDT(i), 0); 1367 IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
939 adapter->tx_ring[i].head = IXGBE_TDH(i); 1368 IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
940 adapter->tx_ring[i].tail = IXGBE_TDT(i); 1369 adapter->tx_ring[i].head = IXGBE_TDH(j);
1370 adapter->tx_ring[i].tail = IXGBE_TDT(j);
1371 /* Disable Tx Head Writeback RO bit, since this hoses
1372 * bookkeeping if things aren't delivered in order.
1373 */
1374 txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
1375 txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
1376 IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl);
941 } 1377 }
942
943 IXGBE_WRITE_REG(hw, IXGBE_TIPG, IXGBE_TIPG_FIBER_DEFAULT);
944} 1378}
945 1379
946#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \ 1380#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
@@ -959,13 +1393,12 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
959 struct ixgbe_hw *hw = &adapter->hw; 1393 struct ixgbe_hw *hw = &adapter->hw;
960 struct net_device *netdev = adapter->netdev; 1394 struct net_device *netdev = adapter->netdev;
961 int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 1395 int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
1396 int i, j;
962 u32 rdlen, rxctrl, rxcsum; 1397 u32 rdlen, rxctrl, rxcsum;
963 u32 random[10]; 1398 u32 random[10];
964 u32 reta, mrqc;
965 int i;
966 u32 fctrl, hlreg0; 1399 u32 fctrl, hlreg0;
967 u32 srrctl;
968 u32 pages; 1400 u32 pages;
1401 u32 reta = 0, mrqc, srrctl;
969 1402
970 /* Decide whether to use packet split mode or not */ 1403 /* Decide whether to use packet split mode or not */
971 if (netdev->mtu > ETH_DATA_LEN) 1404 if (netdev->mtu > ETH_DATA_LEN)
@@ -985,6 +1418,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
985 1418
986 fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); 1419 fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
987 fctrl |= IXGBE_FCTRL_BAM; 1420 fctrl |= IXGBE_FCTRL_BAM;
1421 fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
988 IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl); 1422 IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
989 1423
990 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); 1424 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
@@ -1036,37 +1470,23 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
1036 adapter->rx_ring[i].tail = IXGBE_RDT(i); 1470 adapter->rx_ring[i].tail = IXGBE_RDT(i);
1037 } 1471 }
1038 1472
1039 if (adapter->num_rx_queues > 1) { 1473 if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
1040 /* Random 40bytes used as random key in RSS hash function */
1041 get_random_bytes(&random[0], 40);
1042
1043 switch (adapter->num_rx_queues) {
1044 case 8:
1045 case 4:
1046 /* Bits [3:0] in each byte refers the Rx queue no */
1047 reta = 0x00010203;
1048 break;
1049 case 2:
1050 reta = 0x00010001;
1051 break;
1052 default:
1053 reta = 0x00000000;
1054 break;
1055 }
1056
1057 /* Fill out redirection table */ 1474 /* Fill out redirection table */
1058 for (i = 0; i < 32; i++) { 1475 for (i = 0, j = 0; i < 128; i++, j++) {
1059 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_RETA(0), i, reta); 1476 if (j == adapter->ring_feature[RING_F_RSS].indices)
1060 if (adapter->num_rx_queues > 4) { 1477 j = 0;
1061 i++; 1478 /* reta = 4-byte sliding window of
1062 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_RETA(0), i, 1479 * 0x00..(indices-1)(indices-1)00..etc. */
1063 0x04050607); 1480 reta = (reta << 8) | (j * 0x11);
1064 } 1481 if ((i & 3) == 3)
1482 IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
1065 } 1483 }
1066 1484
1067 /* Fill out hash function seeds */ 1485 /* Fill out hash function seeds */
1486 /* XXX use a random constant here to glue certain flows */
1487 get_random_bytes(&random[0], 40);
1068 for (i = 0; i < 10; i++) 1488 for (i = 0; i < 10; i++)
1069 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_RSSRK(0), i, random[i]); 1489 IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), random[i]);
1070 1490
1071 mrqc = IXGBE_MRQC_RSSEN 1491 mrqc = IXGBE_MRQC_RSSEN
1072 /* Perform hash on these packet types */ 1492 /* Perform hash on these packet types */
@@ -1080,26 +1500,23 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
1080 | IXGBE_MRQC_RSS_FIELD_IPV6_UDP 1500 | IXGBE_MRQC_RSS_FIELD_IPV6_UDP
1081 | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP; 1501 | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
1082 IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); 1502 IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
1503 }
1083 1504
1084 /* Multiqueue and packet checksumming are mutually exclusive. */ 1505 rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
1085 rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); 1506
1507 if (adapter->flags & IXGBE_FLAG_RSS_ENABLED ||
1508 adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED) {
1509 /* Disable indicating checksum in descriptor, enables
1510 * RSS hash */
1086 rxcsum |= IXGBE_RXCSUM_PCSD; 1511 rxcsum |= IXGBE_RXCSUM_PCSD;
1087 IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
1088 } else {
1089 /* Enable Receive Checksum Offload for TCP and UDP */
1090 rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
1091 if (adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED) {
1092 /* Enable IPv4 payload checksum for UDP fragments
1093 * Must be used in conjunction with packet-split. */
1094 rxcsum |= IXGBE_RXCSUM_IPPCSE;
1095 } else {
1096 /* don't need to clear IPPCSE as it defaults to 0 */
1097 }
1098 IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
1099 } 1512 }
1100 /* Enable Receives */ 1513 if (!(rxcsum & IXGBE_RXCSUM_PCSD)) {
1101 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); 1514 /* Enable IPv4 payload checksum for UDP fragments
1102 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 1515 * if PCSD is not set */
1516 rxcsum |= IXGBE_RXCSUM_IPPCSE;
1517 }
1518
1519 IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
1103} 1520}
1104 1521
1105static void ixgbe_vlan_rx_register(struct net_device *netdev, 1522static void ixgbe_vlan_rx_register(struct net_device *netdev,
@@ -1219,6 +1636,42 @@ static void ixgbe_set_multi(struct net_device *netdev)
1219 1636
1220} 1637}
1221 1638
1639static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
1640{
1641 int q_idx;
1642 struct ixgbe_q_vector *q_vector;
1643 int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
1644
1645 /* legacy and MSI only use one vector */
1646 if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
1647 q_vectors = 1;
1648
1649 for (q_idx = 0; q_idx < q_vectors; q_idx++) {
1650 q_vector = &adapter->q_vector[q_idx];
1651 if (!q_vector->rxr_count)
1652 continue;
1653 napi_enable(&q_vector->napi);
1654 }
1655}
1656
1657static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
1658{
1659 int q_idx;
1660 struct ixgbe_q_vector *q_vector;
1661 int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
1662
1663 /* legacy and MSI only use one vector */
1664 if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
1665 q_vectors = 1;
1666
1667 for (q_idx = 0; q_idx < q_vectors; q_idx++) {
1668 q_vector = &adapter->q_vector[q_idx];
1669 if (!q_vector->rxr_count)
1670 continue;
1671 napi_disable(&q_vector->napi);
1672 }
1673}
1674
1222static void ixgbe_configure(struct ixgbe_adapter *adapter) 1675static void ixgbe_configure(struct ixgbe_adapter *adapter)
1223{ 1676{
1224 struct net_device *netdev = adapter->netdev; 1677 struct net_device *netdev = adapter->netdev;
@@ -1238,30 +1691,35 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
1238static int ixgbe_up_complete(struct ixgbe_adapter *adapter) 1691static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
1239{ 1692{
1240 struct net_device *netdev = adapter->netdev; 1693 struct net_device *netdev = adapter->netdev;
1241 int i;
1242 u32 gpie = 0;
1243 struct ixgbe_hw *hw = &adapter->hw; 1694 struct ixgbe_hw *hw = &adapter->hw;
1244 u32 txdctl, rxdctl, mhadd; 1695 int i, j = 0;
1245 int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 1696 int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
1697 u32 txdctl, rxdctl, mhadd;
1698 u32 gpie;
1246 1699
1247 ixgbe_get_hw_control(adapter); 1700 ixgbe_get_hw_control(adapter);
1248 1701
1249 if (adapter->flags & (IXGBE_FLAG_MSIX_ENABLED | 1702 if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) ||
1250 IXGBE_FLAG_MSI_ENABLED)) { 1703 (adapter->flags & IXGBE_FLAG_MSI_ENABLED)) {
1251 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { 1704 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
1252 gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME | 1705 gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME |
1253 IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD); 1706 IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
1254 } else { 1707 } else {
1255 /* MSI only */ 1708 /* MSI only */
1256 gpie = (IXGBE_GPIE_EIAME | 1709 gpie = 0;
1257 IXGBE_GPIE_PBA_SUPPORT);
1258 } 1710 }
1259 IXGBE_WRITE_REG(&adapter->hw, IXGBE_GPIE, gpie); 1711 /* XXX: to interrupt immediately for EICS writes, enable this */
1260 gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE); 1712 /* gpie |= IXGBE_GPIE_EIMEN; */
1713 IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
1261 } 1714 }
1262 1715
1263 mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); 1716 if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
1717 /* legacy interrupts, use EIAM to auto-mask when reading EICR,
1718 * specifically only auto mask tx and rx interrupts */
1719 IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
1720 }
1264 1721
1722 mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
1265 if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { 1723 if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
1266 mhadd &= ~IXGBE_MHADD_MFS_MASK; 1724 mhadd &= ~IXGBE_MHADD_MFS_MASK;
1267 mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT; 1725 mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT;
@@ -1270,15 +1728,21 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
1270 } 1728 }
1271 1729
1272 for (i = 0; i < adapter->num_tx_queues; i++) { 1730 for (i = 0; i < adapter->num_tx_queues; i++) {
1273 txdctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(i)); 1731 j = adapter->tx_ring[i].reg_idx;
1732 txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
1274 txdctl |= IXGBE_TXDCTL_ENABLE; 1733 txdctl |= IXGBE_TXDCTL_ENABLE;
1275 IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(i), txdctl); 1734 IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
1276 } 1735 }
1277 1736
1278 for (i = 0; i < adapter->num_rx_queues; i++) { 1737 for (i = 0; i < adapter->num_rx_queues; i++) {
1279 rxdctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(i)); 1738 j = adapter->rx_ring[i].reg_idx;
1739 rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
1740 /* enable PTHRESH=32 descriptors (half the internal cache)
1741 * and HTHRESH=0 descriptors (to minimize latency on fetch),
1742 * this also removes a pesky rx_no_buffer_count increment */
1743 rxdctl |= 0x0020;
1280 rxdctl |= IXGBE_RXDCTL_ENABLE; 1744 rxdctl |= IXGBE_RXDCTL_ENABLE;
1281 IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(i), rxdctl); 1745 IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl);
1282 } 1746 }
1283 /* enable all receives */ 1747 /* enable all receives */
1284 rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 1748 rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
@@ -1291,7 +1755,11 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
1291 ixgbe_configure_msi_and_legacy(adapter); 1755 ixgbe_configure_msi_and_legacy(adapter);
1292 1756
1293 clear_bit(__IXGBE_DOWN, &adapter->state); 1757 clear_bit(__IXGBE_DOWN, &adapter->state);
1294 napi_enable(&adapter->napi); 1758 ixgbe_napi_enable_all(adapter);
1759
1760 /* clear any pending interrupts, may auto mask */
1761 IXGBE_READ_REG(hw, IXGBE_EICR);
1762
1295 ixgbe_irq_enable(adapter); 1763 ixgbe_irq_enable(adapter);
1296 1764
1297 /* bring the link up in the watchdog, this could race with our first 1765 /* bring the link up in the watchdog, this could race with our first
@@ -1333,7 +1801,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
1333{ 1801{
1334 struct net_device *netdev = pci_get_drvdata(pdev); 1802 struct net_device *netdev = pci_get_drvdata(pdev);
1335 struct ixgbe_adapter *adapter = netdev_priv(netdev); 1803 struct ixgbe_adapter *adapter = netdev_priv(netdev);
1336 u32 err, num_rx_queues = adapter->num_rx_queues; 1804 u32 err;
1337 1805
1338 pci_set_power_state(pdev, PCI_D0); 1806 pci_set_power_state(pdev, PCI_D0);
1339 pci_restore_state(pdev); 1807 pci_restore_state(pdev);
@@ -1349,7 +1817,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
1349 pci_enable_wake(pdev, PCI_D3cold, 0); 1817 pci_enable_wake(pdev, PCI_D3cold, 0);
1350 1818
1351 if (netif_running(netdev)) { 1819 if (netif_running(netdev)) {
1352 err = ixgbe_request_irq(adapter, &num_rx_queues); 1820 err = ixgbe_request_irq(adapter);
1353 if (err) 1821 if (err)
1354 return err; 1822 return err;
1355 } 1823 }
@@ -1449,27 +1917,27 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
1449} 1917}
1450 1918
1451/** 1919/**
1452 * ixgbe_clean_all_tx_rings - Free Tx Buffers for all queues 1920 * ixgbe_clean_all_rx_rings - Free Rx Buffers for all queues
1453 * @adapter: board private structure 1921 * @adapter: board private structure
1454 **/ 1922 **/
1455static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) 1923static void ixgbe_clean_all_rx_rings(struct ixgbe_adapter *adapter)
1456{ 1924{
1457 int i; 1925 int i;
1458 1926
1459 for (i = 0; i < adapter->num_tx_queues; i++) 1927 for (i = 0; i < adapter->num_rx_queues; i++)
1460 ixgbe_clean_tx_ring(adapter, &adapter->tx_ring[i]); 1928 ixgbe_clean_rx_ring(adapter, &adapter->rx_ring[i]);
1461} 1929}
1462 1930
1463/** 1931/**
1464 * ixgbe_clean_all_rx_rings - Free Rx Buffers for all queues 1932 * ixgbe_clean_all_tx_rings - Free Tx Buffers for all queues
1465 * @adapter: board private structure 1933 * @adapter: board private structure
1466 **/ 1934 **/
1467static void ixgbe_clean_all_rx_rings(struct ixgbe_adapter *adapter) 1935static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter)
1468{ 1936{
1469 int i; 1937 int i;
1470 1938
1471 for (i = 0; i < adapter->num_rx_queues; i++) 1939 for (i = 0; i < adapter->num_tx_queues; i++)
1472 ixgbe_clean_rx_ring(adapter, &adapter->rx_ring[i]); 1940 ixgbe_clean_tx_ring(adapter, &adapter->tx_ring[i]);
1473} 1941}
1474 1942
1475void ixgbe_down(struct ixgbe_adapter *adapter) 1943void ixgbe_down(struct ixgbe_adapter *adapter)
@@ -1493,10 +1961,9 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
1493 IXGBE_WRITE_FLUSH(&adapter->hw); 1961 IXGBE_WRITE_FLUSH(&adapter->hw);
1494 msleep(10); 1962 msleep(10);
1495 1963
1496 napi_disable(&adapter->napi);
1497
1498 ixgbe_irq_disable(adapter); 1964 ixgbe_irq_disable(adapter);
1499 1965
1966 ixgbe_napi_disable_all(adapter);
1500 del_timer_sync(&adapter->watchdog_timer); 1967 del_timer_sync(&adapter->watchdog_timer);
1501 1968
1502 netif_carrier_off(netdev); 1969 netif_carrier_off(netdev);
@@ -1547,27 +2014,37 @@ static void ixgbe_shutdown(struct pci_dev *pdev)
1547} 2014}
1548 2015
1549/** 2016/**
1550 * ixgbe_clean - NAPI Rx polling callback 2017 * ixgbe_poll - NAPI Rx polling callback
1551 * @adapter: board private structure 2018 * @napi: structure for representing this polling device
2019 * @budget: how many packets driver is allowed to clean
2020 *
2021 * This function is used for legacy and MSI, NAPI mode
1552 **/ 2022 **/
1553static int ixgbe_clean(struct napi_struct *napi, int budget) 2023static int ixgbe_poll(struct napi_struct *napi, int budget)
1554{ 2024{
1555 struct ixgbe_adapter *adapter = container_of(napi, 2025 struct ixgbe_q_vector *q_vector = container_of(napi,
1556 struct ixgbe_adapter, napi); 2026 struct ixgbe_q_vector, napi);
1557 struct net_device *netdev = adapter->netdev; 2027 struct ixgbe_adapter *adapter = q_vector->adapter;
1558 int tx_cleaned = 0, work_done = 0; 2028 int tx_cleaned = 0, work_done = 0;
1559 2029
1560 /* In non-MSIX case, there is no multi-Tx/Rx queue */ 2030#ifdef CONFIG_DCA
2031 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
2032 ixgbe_update_tx_dca(adapter, adapter->tx_ring);
2033 ixgbe_update_rx_dca(adapter, adapter->rx_ring);
2034 }
2035#endif
2036
1561 tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); 2037 tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
1562 ixgbe_clean_rx_irq(adapter, &adapter->rx_ring[0], &work_done, 2038 ixgbe_clean_rx_irq(adapter, adapter->rx_ring, &work_done, budget);
1563 budget);
1564 2039
1565 if (tx_cleaned) 2040 if (tx_cleaned)
1566 work_done = budget; 2041 work_done = budget;
1567 2042
1568 /* If budget not fully consumed, exit the polling mode */ 2043 /* If budget not fully consumed, exit the polling mode */
1569 if (work_done < budget) { 2044 if (work_done < budget) {
1570 netif_rx_complete(netdev, napi); 2045 netif_rx_complete(adapter->netdev, napi);
2046 if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
2047 ixgbe_set_itr(adapter);
1571 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 2048 if (!test_bit(__IXGBE_DOWN, &adapter->state))
1572 ixgbe_irq_enable(adapter); 2049 ixgbe_irq_enable(adapter);
1573 } 2050 }
@@ -1597,6 +2074,136 @@ static void ixgbe_reset_task(struct work_struct *work)
1597 ixgbe_reinit_locked(adapter); 2074 ixgbe_reinit_locked(adapter);
1598} 2075}
1599 2076
2077static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
2078 int vectors)
2079{
2080 int err, vector_threshold;
2081
2082 /* We'll want at least 3 (vector_threshold):
2083 * 1) TxQ[0] Cleanup
2084 * 2) RxQ[0] Cleanup
2085 * 3) Other (Link Status Change, etc.)
2086 * 4) TCP Timer (optional)
2087 */
2088 vector_threshold = MIN_MSIX_COUNT;
2089
2090 /* The more we get, the more we will assign to Tx/Rx Cleanup
2091 * for the separate queues...where Rx Cleanup >= Tx Cleanup.
2092 * Right now, we simply care about how many we'll get; we'll
2093 * set them up later while requesting irq's.
2094 */
2095 while (vectors >= vector_threshold) {
2096 err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
2097 vectors);
2098 if (!err) /* Success in acquiring all requested vectors. */
2099 break;
2100 else if (err < 0)
2101 vectors = 0; /* Nasty failure, quit now */
2102 else /* err == number of vectors we should try again with */
2103 vectors = err;
2104 }
2105
2106 if (vectors < vector_threshold) {
2107 /* Can't allocate enough MSI-X interrupts? Oh well.
2108 * This just means we'll go with either a single MSI
2109 * vector or fall back to legacy interrupts.
2110 */
2111 DPRINTK(HW, DEBUG, "Unable to allocate MSI-X interrupts\n");
2112 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
2113 kfree(adapter->msix_entries);
2114 adapter->msix_entries = NULL;
2115 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
2116 adapter->num_tx_queues = 1;
2117 adapter->num_rx_queues = 1;
2118 } else {
2119 adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
2120 adapter->num_msix_vectors = vectors;
2121 }
2122}
2123
2124static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
2125{
2126 int nrq, ntq;
2127 int feature_mask = 0, rss_i, rss_m;
2128
2129 /* Number of supported queues */
2130 switch (adapter->hw.mac.type) {
2131 case ixgbe_mac_82598EB:
2132 rss_i = adapter->ring_feature[RING_F_RSS].indices;
2133 rss_m = 0;
2134 feature_mask |= IXGBE_FLAG_RSS_ENABLED;
2135
2136 switch (adapter->flags & feature_mask) {
2137 case (IXGBE_FLAG_RSS_ENABLED):
2138 rss_m = 0xF;
2139 nrq = rss_i;
2140#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2141 ntq = rss_i;
2142#else
2143 ntq = 1;
2144#endif
2145 break;
2146 case 0:
2147 default:
2148 rss_i = 0;
2149 rss_m = 0;
2150 nrq = 1;
2151 ntq = 1;
2152 break;
2153 }
2154
2155 adapter->ring_feature[RING_F_RSS].indices = rss_i;
2156 adapter->ring_feature[RING_F_RSS].mask = rss_m;
2157 break;
2158 default:
2159 nrq = 1;
2160 ntq = 1;
2161 break;
2162 }
2163
2164 adapter->num_rx_queues = nrq;
2165 adapter->num_tx_queues = ntq;
2166}
2167
2168/**
2169 * ixgbe_cache_ring_register - Descriptor ring to register mapping
2170 * @adapter: board private structure to initialize
2171 *
2172 * Once we know the feature-set enabled for the device, we'll cache
2173 * the register offset the descriptor ring is assigned to.
2174 **/
2175static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
2176{
2177 /* TODO: Remove all uses of the indices in the cases where multiple
2178 * features are OR'd together, if the feature set makes sense.
2179 */
2180 int feature_mask = 0, rss_i;
2181 int i, txr_idx, rxr_idx;
2182
2183 /* Number of supported queues */
2184 switch (adapter->hw.mac.type) {
2185 case ixgbe_mac_82598EB:
2186 rss_i = adapter->ring_feature[RING_F_RSS].indices;
2187 txr_idx = 0;
2188 rxr_idx = 0;
2189 feature_mask |= IXGBE_FLAG_RSS_ENABLED;
2190 switch (adapter->flags & feature_mask) {
2191 case (IXGBE_FLAG_RSS_ENABLED):
2192 for (i = 0; i < adapter->num_rx_queues; i++)
2193 adapter->rx_ring[i].reg_idx = i;
2194 for (i = 0; i < adapter->num_tx_queues; i++)
2195 adapter->tx_ring[i].reg_idx = i;
2196 break;
2197 case 0:
2198 default:
2199 break;
2200 }
2201 break;
2202 default:
2203 break;
2204 }
2205}
2206
1600/** 2207/**
1601 * ixgbe_alloc_queues - Allocate memory for all rings 2208 * ixgbe_alloc_queues - Allocate memory for all rings
1602 * @adapter: board private structure to initialize 2209 * @adapter: board private structure to initialize
@@ -1612,25 +2219,167 @@ static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
1612 adapter->tx_ring = kcalloc(adapter->num_tx_queues, 2219 adapter->tx_ring = kcalloc(adapter->num_tx_queues,
1613 sizeof(struct ixgbe_ring), GFP_KERNEL); 2220 sizeof(struct ixgbe_ring), GFP_KERNEL);
1614 if (!adapter->tx_ring) 2221 if (!adapter->tx_ring)
1615 return -ENOMEM; 2222 goto err_tx_ring_allocation;
1616
1617 for (i = 0; i < adapter->num_tx_queues; i++)
1618 adapter->tx_ring[i].count = IXGBE_DEFAULT_TXD;
1619 2223
1620 adapter->rx_ring = kcalloc(adapter->num_rx_queues, 2224 adapter->rx_ring = kcalloc(adapter->num_rx_queues,
1621 sizeof(struct ixgbe_ring), GFP_KERNEL); 2225 sizeof(struct ixgbe_ring), GFP_KERNEL);
1622 if (!adapter->rx_ring) { 2226 if (!adapter->rx_ring)
1623 kfree(adapter->tx_ring); 2227 goto err_rx_ring_allocation;
1624 return -ENOMEM;
1625 }
1626 2228
2229 for (i = 0; i < adapter->num_tx_queues; i++) {
2230 adapter->tx_ring[i].count = IXGBE_DEFAULT_TXD;
2231 adapter->tx_ring[i].queue_index = i;
2232 }
1627 for (i = 0; i < adapter->num_rx_queues; i++) { 2233 for (i = 0; i < adapter->num_rx_queues; i++) {
1628 adapter->rx_ring[i].adapter = adapter;
1629 adapter->rx_ring[i].itr_register = IXGBE_EITR(i);
1630 adapter->rx_ring[i].count = IXGBE_DEFAULT_RXD; 2234 adapter->rx_ring[i].count = IXGBE_DEFAULT_RXD;
2235 adapter->rx_ring[i].queue_index = i;
1631 } 2236 }
1632 2237
2238 ixgbe_cache_ring_register(adapter);
2239
1633 return 0; 2240 return 0;
2241
2242err_rx_ring_allocation:
2243 kfree(adapter->tx_ring);
2244err_tx_ring_allocation:
2245 return -ENOMEM;
2246}
2247
2248/**
2249 * ixgbe_set_interrupt_capability - set MSI-X or MSI if supported
2250 * @adapter: board private structure to initialize
2251 *
2252 * Attempt to configure the interrupts using the best available
2253 * capabilities of the hardware and the kernel.
2254 **/
2255static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
2256 *adapter)
2257{
2258 int err = 0;
2259 int vector, v_budget;
2260
2261 /*
2262 * It's easy to be greedy for MSI-X vectors, but it really
2263 * doesn't do us much good if we have a lot more vectors
2264 * than CPU's. So let's be conservative and only ask for
2265 * (roughly) twice the number of vectors as there are CPU's.
2266 */
2267 v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
2268 (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
2269
2270 /*
2271 * At the same time, hardware can only support a maximum of
2272 * MAX_MSIX_COUNT vectors. With features such as RSS and VMDq,
2273 * we can easily reach upwards of 64 Rx descriptor queues and
2274 * 32 Tx queues. Thus, we cap it off in those rare cases where
2275 * the cpu count also exceeds our vector limit.
2276 */
2277 v_budget = min(v_budget, MAX_MSIX_COUNT);
2278
2279 /* A failure in MSI-X entry allocation isn't fatal, but it does
2280 * mean we disable MSI-X capabilities of the adapter. */
2281 adapter->msix_entries = kcalloc(v_budget,
2282 sizeof(struct msix_entry), GFP_KERNEL);
2283 if (!adapter->msix_entries) {
2284 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
2285 ixgbe_set_num_queues(adapter);
2286 kfree(adapter->tx_ring);
2287 kfree(adapter->rx_ring);
2288 err = ixgbe_alloc_queues(adapter);
2289 if (err) {
2290 DPRINTK(PROBE, ERR, "Unable to allocate memory "
2291 "for queues\n");
2292 goto out;
2293 }
2294
2295 goto try_msi;
2296 }
2297
2298 for (vector = 0; vector < v_budget; vector++)
2299 adapter->msix_entries[vector].entry = vector;
2300
2301 ixgbe_acquire_msix_vectors(adapter, v_budget);
2302
2303 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
2304 goto out;
2305
2306try_msi:
2307 err = pci_enable_msi(adapter->pdev);
2308 if (!err) {
2309 adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
2310 } else {
2311 DPRINTK(HW, DEBUG, "Unable to allocate MSI interrupt, "
2312 "falling back to legacy. Error: %d\n", err);
2313 /* reset err */
2314 err = 0;
2315 }
2316
2317out:
2318#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2319 /* Notify the stack of the (possibly) reduced Tx Queue count. */
2320 adapter->netdev->egress_subqueue_count = adapter->num_tx_queues;
2321#endif
2322
2323 return err;
2324}
2325
2326static void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
2327{
2328 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
2329 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
2330 pci_disable_msix(adapter->pdev);
2331 kfree(adapter->msix_entries);
2332 adapter->msix_entries = NULL;
2333 } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
2334 adapter->flags &= ~IXGBE_FLAG_MSI_ENABLED;
2335 pci_disable_msi(adapter->pdev);
2336 }
2337 return;
2338}
2339
2340/**
2341 * ixgbe_init_interrupt_scheme - Determine proper interrupt scheme
2342 * @adapter: board private structure to initialize
2343 *
2344 * We determine which interrupt scheme to use based on...
2345 * - Kernel support (MSI, MSI-X)
2346 * - which can be user-defined (via MODULE_PARAM)
2347 * - Hardware queue count (num_*_queues)
2348 * - defined by miscellaneous hardware support/features (RSS, etc.)
2349 **/
2350static int __devinit ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
2351{
2352 int err;
2353
2354 /* Number of supported queues */
2355 ixgbe_set_num_queues(adapter);
2356
2357 err = ixgbe_alloc_queues(adapter);
2358 if (err) {
2359 DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
2360 goto err_alloc_queues;
2361 }
2362
2363 err = ixgbe_set_interrupt_capability(adapter);
2364 if (err) {
2365 DPRINTK(PROBE, ERR, "Unable to setup interrupt capabilities\n");
2366 goto err_set_interrupt;
2367 }
2368
2369 DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
2370 "Tx Queue count = %u\n",
2371 (adapter->num_rx_queues > 1) ? "Enabled" :
2372 "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
2373
2374 set_bit(__IXGBE_DOWN, &adapter->state);
2375
2376 return 0;
2377
2378err_set_interrupt:
2379 kfree(adapter->tx_ring);
2380 kfree(adapter->rx_ring);
2381err_alloc_queues:
2382 return err;
1634} 2383}
1635 2384
1636/** 2385/**
@@ -1645,11 +2394,22 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
1645{ 2394{
1646 struct ixgbe_hw *hw = &adapter->hw; 2395 struct ixgbe_hw *hw = &adapter->hw;
1647 struct pci_dev *pdev = adapter->pdev; 2396 struct pci_dev *pdev = adapter->pdev;
2397 unsigned int rss;
2398
2399 /* Set capability flags */
2400 rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus());
2401 adapter->ring_feature[RING_F_RSS].indices = rss;
2402 adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
2403
2404 /* Enable Dynamic interrupt throttling by default */
2405 adapter->rx_eitr = 1;
2406 adapter->tx_eitr = 1;
1648 2407
1649 /* default flow control settings */ 2408 /* default flow control settings */
1650 hw->fc.original_type = ixgbe_fc_full; 2409 hw->fc.original_type = ixgbe_fc_full;
1651 hw->fc.type = ixgbe_fc_full; 2410 hw->fc.type = ixgbe_fc_full;
1652 2411
2412 /* select 10G link by default */
1653 hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN; 2413 hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
1654 if (hw->mac.ops.reset(hw)) { 2414 if (hw->mac.ops.reset(hw)) {
1655 dev_err(&pdev->dev, "HW Init failed\n"); 2415 dev_err(&pdev->dev, "HW Init failed\n");
@@ -1667,16 +2427,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
1667 return -EIO; 2427 return -EIO;
1668 } 2428 }
1669 2429
1670 /* Set the default values */ 2430 /* enable rx csum by default */
1671 adapter->num_rx_queues = IXGBE_DEFAULT_RXQ;
1672 adapter->num_tx_queues = 1;
1673 adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; 2431 adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
1674 2432
1675 if (ixgbe_alloc_queues(adapter)) {
1676 dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
1677 return -ENOMEM;
1678 }
1679
1680 set_bit(__IXGBE_DOWN, &adapter->state); 2433 set_bit(__IXGBE_DOWN, &adapter->state);
1681 2434
1682 return 0; 2435 return 0;
@@ -1716,7 +2469,6 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
1716 return -ENOMEM; 2469 return -ENOMEM;
1717 } 2470 }
1718 2471
1719 txdr->adapter = adapter;
1720 txdr->next_to_use = 0; 2472 txdr->next_to_use = 0;
1721 txdr->next_to_clean = 0; 2473 txdr->next_to_clean = 0;
1722 txdr->work_limit = txdr->count; 2474 txdr->work_limit = txdr->count;
@@ -1735,7 +2487,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
1735 struct ixgbe_ring *rxdr) 2487 struct ixgbe_ring *rxdr)
1736{ 2488{
1737 struct pci_dev *pdev = adapter->pdev; 2489 struct pci_dev *pdev = adapter->pdev;
1738 int size, desc_len; 2490 int size;
1739 2491
1740 size = sizeof(struct ixgbe_rx_buffer) * rxdr->count; 2492 size = sizeof(struct ixgbe_rx_buffer) * rxdr->count;
1741 rxdr->rx_buffer_info = vmalloc(size); 2493 rxdr->rx_buffer_info = vmalloc(size);
@@ -1746,10 +2498,8 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
1746 } 2498 }
1747 memset(rxdr->rx_buffer_info, 0, size); 2499 memset(rxdr->rx_buffer_info, 0, size);
1748 2500
1749 desc_len = sizeof(union ixgbe_adv_rx_desc);
1750
1751 /* Round up to nearest 4K */ 2501 /* Round up to nearest 4K */
1752 rxdr->size = rxdr->count * desc_len; 2502 rxdr->size = rxdr->count * sizeof(union ixgbe_adv_rx_desc);
1753 rxdr->size = ALIGN(rxdr->size, 4096); 2503 rxdr->size = ALIGN(rxdr->size, 4096);
1754 2504
1755 rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); 2505 rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
@@ -1763,7 +2513,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
1763 2513
1764 rxdr->next_to_clean = 0; 2514 rxdr->next_to_clean = 0;
1765 rxdr->next_to_use = 0; 2515 rxdr->next_to_use = 0;
1766 rxdr->adapter = adapter;
1767 2516
1768 return 0; 2517 return 0;
1769} 2518}
@@ -1841,8 +2590,7 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
1841} 2590}
1842 2591
1843/** 2592/**
1844 * ixgbe_setup_all_tx_resources - wrapper to allocate Tx resources 2593 * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
1845 * (Descriptors) for all queues
1846 * @adapter: board private structure 2594 * @adapter: board private structure
1847 * 2595 *
1848 * If this function returns with an error, then it's possible one or 2596 * If this function returns with an error, then it's possible one or
@@ -1868,8 +2616,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
1868} 2616}
1869 2617
1870/** 2618/**
1871 * ixgbe_setup_all_rx_resources - wrapper to allocate Rx resources 2619 * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
1872 * (Descriptors) for all queues
1873 * @adapter: board private structure 2620 * @adapter: board private structure
1874 * 2621 *
1875 * If this function returns with an error, then it's possible one or 2622 * If this function returns with an error, then it's possible one or
@@ -1911,6 +2658,9 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
1911 (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) 2658 (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
1912 return -EINVAL; 2659 return -EINVAL;
1913 2660
2661 DPRINTK(PROBE, INFO, "changing MTU from %d to %d\n",
2662 netdev->mtu, new_mtu);
2663 /* must set new MTU before calling down or up */
1914 netdev->mtu = new_mtu; 2664 netdev->mtu = new_mtu;
1915 2665
1916 if (netif_running(netdev)) 2666 if (netif_running(netdev))
@@ -1935,23 +2685,16 @@ static int ixgbe_open(struct net_device *netdev)
1935{ 2685{
1936 struct ixgbe_adapter *adapter = netdev_priv(netdev); 2686 struct ixgbe_adapter *adapter = netdev_priv(netdev);
1937 int err; 2687 int err;
1938 u32 num_rx_queues = adapter->num_rx_queues;
1939 2688
1940 /* disallow open during test */ 2689 /* disallow open during test */
1941 if (test_bit(__IXGBE_TESTING, &adapter->state)) 2690 if (test_bit(__IXGBE_TESTING, &adapter->state))
1942 return -EBUSY; 2691 return -EBUSY;
1943 2692
1944try_intr_reinit:
1945 /* allocate transmit descriptors */ 2693 /* allocate transmit descriptors */
1946 err = ixgbe_setup_all_tx_resources(adapter); 2694 err = ixgbe_setup_all_tx_resources(adapter);
1947 if (err) 2695 if (err)
1948 goto err_setup_tx; 2696 goto err_setup_tx;
1949 2697
1950 if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
1951 num_rx_queues = 1;
1952 adapter->num_rx_queues = num_rx_queues;
1953 }
1954
1955 /* allocate receive descriptors */ 2698 /* allocate receive descriptors */
1956 err = ixgbe_setup_all_rx_resources(adapter); 2699 err = ixgbe_setup_all_rx_resources(adapter);
1957 if (err) 2700 if (err)
@@ -1959,31 +2702,10 @@ try_intr_reinit:
1959 2702
1960 ixgbe_configure(adapter); 2703 ixgbe_configure(adapter);
1961 2704
1962 err = ixgbe_request_irq(adapter, &num_rx_queues); 2705 err = ixgbe_request_irq(adapter);
1963 if (err) 2706 if (err)
1964 goto err_req_irq; 2707 goto err_req_irq;
1965 2708
1966 /* ixgbe_request might have reduced num_rx_queues */
1967 if (num_rx_queues < adapter->num_rx_queues) {
1968 /* We didn't get MSI-X, so we need to release everything,
1969 * set our Rx queue count to num_rx_queues, and redo the
1970 * whole init process.
1971 */
1972 ixgbe_free_irq(adapter);
1973 if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
1974 pci_disable_msi(adapter->pdev);
1975 adapter->flags &= ~IXGBE_FLAG_MSI_ENABLED;
1976 }
1977 ixgbe_free_all_rx_resources(adapter);
1978 ixgbe_free_all_tx_resources(adapter);
1979 adapter->num_rx_queues = num_rx_queues;
1980
1981 /* Reset the hardware, and start over. */
1982 ixgbe_reset(adapter);
1983
1984 goto try_intr_reinit;
1985 }
1986
1987 err = ixgbe_up_complete(adapter); 2709 err = ixgbe_up_complete(adapter);
1988 if (err) 2710 if (err)
1989 goto err_up; 2711 goto err_up;
@@ -2119,6 +2841,9 @@ static void ixgbe_watchdog(unsigned long data)
2119 struct net_device *netdev = adapter->netdev; 2841 struct net_device *netdev = adapter->netdev;
2120 bool link_up; 2842 bool link_up;
2121 u32 link_speed = 0; 2843 u32 link_speed = 0;
2844#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2845 int i;
2846#endif
2122 2847
2123 adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up); 2848 adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
2124 2849
@@ -2140,6 +2865,10 @@ static void ixgbe_watchdog(unsigned long data)
2140 2865
2141 netif_carrier_on(netdev); 2866 netif_carrier_on(netdev);
2142 netif_wake_queue(netdev); 2867 netif_wake_queue(netdev);
2868#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2869 for (i = 0; i < adapter->num_tx_queues; i++)
2870 netif_wake_subqueue(netdev, i);
2871#endif
2143 } else { 2872 } else {
2144 /* Force detection of hung controller */ 2873 /* Force detection of hung controller */
2145 adapter->detect_tx_hung = true; 2874 adapter->detect_tx_hung = true;
@@ -2154,10 +2883,23 @@ static void ixgbe_watchdog(unsigned long data)
2154 2883
2155 ixgbe_update_stats(adapter); 2884 ixgbe_update_stats(adapter);
2156 2885
2157 /* Reset the timer */ 2886 if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
2158 if (!test_bit(__IXGBE_DOWN, &adapter->state)) 2887 /* Cause software interrupt to ensure rx rings are cleaned */
2888 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
2889 u32 eics =
2890 (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
2891 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, eics);
2892 } else {
2893 /* for legacy and MSI interrupts don't set any bits that
2894 * are enabled for EIAM, because this operation would
2895 * set *both* EIMS and EICS for any bit in EIAM */
2896 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
2897 (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
2898 }
2899 /* Reset the timer */
2159 mod_timer(&adapter->watchdog_timer, 2900 mod_timer(&adapter->watchdog_timer,
2160 round_jiffies(jiffies + 2 * HZ)); 2901 round_jiffies(jiffies + 2 * HZ));
2902 }
2161} 2903}
2162 2904
2163static int ixgbe_tso(struct ixgbe_adapter *adapter, 2905static int ixgbe_tso(struct ixgbe_adapter *adapter,
@@ -2170,7 +2912,6 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
2170 struct ixgbe_tx_buffer *tx_buffer_info; 2912 struct ixgbe_tx_buffer *tx_buffer_info;
2171 u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; 2913 u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
2172 u32 mss_l4len_idx = 0, l4len; 2914 u32 mss_l4len_idx = 0, l4len;
2173 *hdr_len = 0;
2174 2915
2175 if (skb_is_gso(skb)) { 2916 if (skb_is_gso(skb)) {
2176 if (skb_header_cloned(skb)) { 2917 if (skb_header_cloned(skb)) {
@@ -2454,7 +3195,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
2454{ 3195{
2455 struct ixgbe_adapter *adapter = netdev_priv(netdev); 3196 struct ixgbe_adapter *adapter = netdev_priv(netdev);
2456 3197
3198#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3199 netif_stop_subqueue(netdev, tx_ring->queue_index);
3200#else
2457 netif_stop_queue(netdev); 3201 netif_stop_queue(netdev);
3202#endif
2458 /* Herbert's original patch had: 3203 /* Herbert's original patch had:
2459 * smp_mb__after_netif_stop_queue(); 3204 * smp_mb__after_netif_stop_queue();
2460 * but since that doesn't exist yet, just open code it. */ 3205 * but since that doesn't exist yet, just open code it. */
@@ -2466,7 +3211,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
2466 return -EBUSY; 3211 return -EBUSY;
2467 3212
2468 /* A reprieve! - use start_queue because it doesn't call schedule */ 3213 /* A reprieve! - use start_queue because it doesn't call schedule */
3214#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3215 netif_wake_subqueue(netdev, tx_ring->queue_index);
3216#else
2469 netif_wake_queue(netdev); 3217 netif_wake_queue(netdev);
3218#endif
2470 ++adapter->restart_queue; 3219 ++adapter->restart_queue;
2471 return 0; 3220 return 0;
2472} 3221}
@@ -2487,15 +3236,18 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
2487 unsigned int len = skb->len; 3236 unsigned int len = skb->len;
2488 unsigned int first; 3237 unsigned int first;
2489 unsigned int tx_flags = 0; 3238 unsigned int tx_flags = 0;
2490 u8 hdr_len; 3239 u8 hdr_len = 0;
2491 int tso; 3240 int r_idx = 0, tso;
2492 unsigned int mss = 0; 3241 unsigned int mss = 0;
2493 int count = 0; 3242 int count = 0;
2494 unsigned int f; 3243 unsigned int f;
2495 unsigned int nr_frags = skb_shinfo(skb)->nr_frags; 3244 unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
2496 len -= skb->data_len; 3245 len -= skb->data_len;
3246#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3247 r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
3248#endif
3249 tx_ring = &adapter->tx_ring[r_idx];
2497 3250
2498 tx_ring = adapter->tx_ring;
2499 3251
2500 if (skb->len <= 0) { 3252 if (skb->len <= 0) {
2501 dev_kfree_skb(skb); 3253 dev_kfree_skb(skb);
@@ -2604,6 +3356,31 @@ static void ixgbe_netpoll(struct net_device *netdev)
2604#endif 3356#endif
2605 3357
2606/** 3358/**
3359 * ixgbe_napi_add_all - prep napi structs for use
3360 * @adapter: private struct
3361 * helper function to napi_add each possible q_vector->napi
3362 */
3363static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
3364{
3365 int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
3366 int (*poll)(struct napi_struct *, int);
3367
3368 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
3369 poll = &ixgbe_clean_rxonly;
3370 } else {
3371 poll = &ixgbe_poll;
3372 /* only one q_vector for legacy modes */
3373 q_vectors = 1;
3374 }
3375
3376 for (i = 0; i < q_vectors; i++) {
3377 struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
3378 netif_napi_add(adapter->netdev, &q_vector->napi,
3379 (*poll), 64);
3380 }
3381}
3382
3383/**
2607 * ixgbe_probe - Device Initialization Routine 3384 * ixgbe_probe - Device Initialization Routine
2608 * @pdev: PCI device information struct 3385 * @pdev: PCI device information struct
2609 * @ent: entry in ixgbe_pci_tbl 3386 * @ent: entry in ixgbe_pci_tbl
@@ -2655,7 +3432,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
2655 3432
2656 pci_set_master(pdev); 3433 pci_set_master(pdev);
2657 3434
3435#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3436 netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES);
3437#else
2658 netdev = alloc_etherdev(sizeof(struct ixgbe_adapter)); 3438 netdev = alloc_etherdev(sizeof(struct ixgbe_adapter));
3439#endif
2659 if (!netdev) { 3440 if (!netdev) {
2660 err = -ENOMEM; 3441 err = -ENOMEM;
2661 goto err_alloc_etherdev; 3442 goto err_alloc_etherdev;
@@ -2696,7 +3477,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
2696 ixgbe_set_ethtool_ops(netdev); 3477 ixgbe_set_ethtool_ops(netdev);
2697 netdev->tx_timeout = &ixgbe_tx_timeout; 3478 netdev->tx_timeout = &ixgbe_tx_timeout;
2698 netdev->watchdog_timeo = 5 * HZ; 3479 netdev->watchdog_timeo = 5 * HZ;
2699 netif_napi_add(netdev, &adapter->napi, ixgbe_clean, 64);
2700 netdev->vlan_rx_register = ixgbe_vlan_rx_register; 3480 netdev->vlan_rx_register = ixgbe_vlan_rx_register;
2701 netdev->vlan_rx_add_vid = ixgbe_vlan_rx_add_vid; 3481 netdev->vlan_rx_add_vid = ixgbe_vlan_rx_add_vid;
2702 netdev->vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid; 3482 netdev->vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid;
@@ -2719,6 +3499,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
2719 3499
2720 /* Setup hw api */ 3500 /* Setup hw api */
2721 memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops)); 3501 memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
3502 hw->mac.type = ii->mac;
2722 3503
2723 err = ii->get_invariants(hw); 3504 err = ii->get_invariants(hw);
2724 if (err) 3505 if (err)
@@ -2741,6 +3522,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
2741 if (pci_using_dac) 3522 if (pci_using_dac)
2742 netdev->features |= NETIF_F_HIGHDMA; 3523 netdev->features |= NETIF_F_HIGHDMA;
2743 3524
3525#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3526 netdev->features |= NETIF_F_MULTI_QUEUE;
3527#endif
2744 3528
2745 /* make sure the EEPROM is good */ 3529 /* make sure the EEPROM is good */
2746 if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) { 3530 if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
@@ -2770,9 +3554,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
2770 hw->fc.low_water = IXGBE_DEFAULT_FCRTL; 3554 hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
2771 hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; 3555 hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
2772 3556
2773 /* Interrupt Throttle Rate */ 3557 err = ixgbe_init_interrupt_scheme(adapter);
2774 adapter->rx_eitr = (1000000 / IXGBE_DEFAULT_ITR_RX_USECS); 3558 if (err)
2775 adapter->tx_eitr = (1000000 / IXGBE_DEFAULT_ITR_TX_USECS); 3559 goto err_sw_init;
2776 3560
2777 /* print bus type/speed/width info */ 3561 /* print bus type/speed/width info */
2778 pci_read_config_word(pdev, IXGBE_PCI_LINK_STATUS, &link_status); 3562 pci_read_config_word(pdev, IXGBE_PCI_LINK_STATUS, &link_status);
@@ -2808,12 +3592,27 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
2808 3592
2809 netif_carrier_off(netdev); 3593 netif_carrier_off(netdev);
2810 netif_stop_queue(netdev); 3594 netif_stop_queue(netdev);
3595#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3596 for (i = 0; i < adapter->num_tx_queues; i++)
3597 netif_stop_subqueue(netdev, i);
3598#endif
3599
3600 ixgbe_napi_add_all(adapter);
2811 3601
2812 strcpy(netdev->name, "eth%d"); 3602 strcpy(netdev->name, "eth%d");
2813 err = register_netdev(netdev); 3603 err = register_netdev(netdev);
2814 if (err) 3604 if (err)
2815 goto err_register; 3605 goto err_register;
2816 3606
3607#ifdef CONFIG_DCA
3608 if (dca_add_requester(&pdev->dev) == IXGBE_SUCCESS) {
3609 adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
3610 /* always use CB2 mode, difference is masked
3611 * in the CB driver */
3612 IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
3613 ixgbe_setup_dca(adapter);
3614 }
3615#endif
2817 3616
2818 dev_info(&pdev->dev, "Intel(R) 10 Gigabit Network Connection\n"); 3617 dev_info(&pdev->dev, "Intel(R) 10 Gigabit Network Connection\n");
2819 cards_found++; 3618 cards_found++;
@@ -2823,6 +3622,7 @@ err_register:
2823 ixgbe_release_hw_control(adapter); 3622 ixgbe_release_hw_control(adapter);
2824err_hw_init: 3623err_hw_init:
2825err_sw_init: 3624err_sw_init:
3625 ixgbe_reset_interrupt_capability(adapter);
2826err_eeprom: 3626err_eeprom:
2827 iounmap(hw->hw_addr); 3627 iounmap(hw->hw_addr);
2828err_ioremap: 3628err_ioremap:
@@ -2854,16 +3654,27 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
2854 3654
2855 flush_scheduled_work(); 3655 flush_scheduled_work();
2856 3656
3657#ifdef CONFIG_DCA
3658 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
3659 adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
3660 dca_remove_requester(&pdev->dev);
3661 IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 1);
3662 }
3663
3664#endif
2857 unregister_netdev(netdev); 3665 unregister_netdev(netdev);
2858 3666
2859 ixgbe_release_hw_control(adapter); 3667 ixgbe_reset_interrupt_capability(adapter);
2860 3668
2861 kfree(adapter->tx_ring); 3669 ixgbe_release_hw_control(adapter);
2862 kfree(adapter->rx_ring);
2863 3670
2864 iounmap(adapter->hw.hw_addr); 3671 iounmap(adapter->hw.hw_addr);
2865 pci_release_regions(pdev); 3672 pci_release_regions(pdev);
2866 3673
3674 DPRINTK(PROBE, INFO, "complete\n");
3675 kfree(adapter->tx_ring);
3676 kfree(adapter->rx_ring);
3677
2867 free_netdev(netdev); 3678 free_netdev(netdev);
2868 3679
2869 pci_disable_device(pdev); 3680 pci_disable_device(pdev);
@@ -2975,6 +3786,10 @@ static int __init ixgbe_init_module(void)
2975 3786
2976 printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright); 3787 printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright);
2977 3788
3789#ifdef CONFIG_DCA
3790 dca_register_notify(&dca_notifier);
3791
3792#endif
2978 ret = pci_register_driver(&ixgbe_driver); 3793 ret = pci_register_driver(&ixgbe_driver);
2979 return ret; 3794 return ret;
2980} 3795}
@@ -2988,8 +3803,25 @@ module_init(ixgbe_init_module);
2988 **/ 3803 **/
2989static void __exit ixgbe_exit_module(void) 3804static void __exit ixgbe_exit_module(void)
2990{ 3805{
3806#ifdef CONFIG_DCA
3807 dca_unregister_notify(&dca_notifier);
3808#endif
2991 pci_unregister_driver(&ixgbe_driver); 3809 pci_unregister_driver(&ixgbe_driver);
2992} 3810}
3811
3812#ifdef CONFIG_DCA
3813static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
3814 void *p)
3815{
3816 int ret_val;
3817
3818 ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event,
3819 __ixgbe_notify_dca);
3820
3821 return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
3822}
3823#endif /* CONFIG_DCA */
3824
2993module_exit(ixgbe_exit_module); 3825module_exit(ixgbe_exit_module);
2994 3826
2995/* ixgbe_main.c */ 3827/* ixgbe_main.c */
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index c72787adeba3..6d8e5c4cf858 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -50,6 +50,8 @@
50 * Possible values '1' for enable , '0' for disable. 50 * Possible values '1' for enable , '0' for disable.
51 * Default is '2' - which means disable in promisc mode 51 * Default is '2' - which means disable in promisc mode
52 * and enable in non-promiscuous mode. 52 * and enable in non-promiscuous mode.
53 * multiq: This parameter used to enable/disable MULTIQUEUE support.
54 * Possible values '1' for enable and '0' for disable. Default is '0'
53 ************************************************************************/ 55 ************************************************************************/
54 56
55#include <linux/module.h> 57#include <linux/module.h>
@@ -84,7 +86,7 @@
84#include "s2io.h" 86#include "s2io.h"
85#include "s2io-regs.h" 87#include "s2io-regs.h"
86 88
87#define DRV_VERSION "2.0.26.15-2" 89#define DRV_VERSION "2.0.26.19"
88 90
89/* S2io Driver name & version. */ 91/* S2io Driver name & version. */
90static char s2io_driver_name[] = "Neterion"; 92static char s2io_driver_name[] = "Neterion";
@@ -386,6 +388,26 @@ static void s2io_vlan_rx_register(struct net_device *dev,
386/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ 388/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
387static int vlan_strip_flag; 389static int vlan_strip_flag;
388 390
391/* Unregister the vlan */
392static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
393{
394 int i;
395 struct s2io_nic *nic = dev->priv;
396 unsigned long flags[MAX_TX_FIFOS];
397 struct mac_info *mac_control = &nic->mac_control;
398 struct config_param *config = &nic->config;
399
400 for (i = 0; i < config->tx_fifo_num; i++)
401 spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags[i]);
402
403 if (nic->vlgrp)
404 vlan_group_set_device(nic->vlgrp, vid, NULL);
405
406 for (i = config->tx_fifo_num - 1; i >= 0; i--)
407 spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock,
408 flags[i]);
409}
410
389/* 411/*
390 * Constants to be programmed into the Xena's registers, to configure 412 * Constants to be programmed into the Xena's registers, to configure
391 * the XAUI. 413 * the XAUI.
@@ -456,10 +478,9 @@ MODULE_VERSION(DRV_VERSION);
456 478
457 479
458/* Module Loadable parameters. */ 480/* Module Loadable parameters. */
459S2IO_PARM_INT(tx_fifo_num, 1); 481S2IO_PARM_INT(tx_fifo_num, FIFO_DEFAULT_NUM);
460S2IO_PARM_INT(rx_ring_num, 1); 482S2IO_PARM_INT(rx_ring_num, 1);
461 483S2IO_PARM_INT(multiq, 0);
462
463S2IO_PARM_INT(rx_ring_mode, 1); 484S2IO_PARM_INT(rx_ring_mode, 1);
464S2IO_PARM_INT(use_continuous_tx_intrs, 1); 485S2IO_PARM_INT(use_continuous_tx_intrs, 1);
465S2IO_PARM_INT(rmac_pause_time, 0x100); 486S2IO_PARM_INT(rmac_pause_time, 0x100);
@@ -469,6 +490,8 @@ S2IO_PARM_INT(shared_splits, 0);
469S2IO_PARM_INT(tmac_util_period, 5); 490S2IO_PARM_INT(tmac_util_period, 5);
470S2IO_PARM_INT(rmac_util_period, 5); 491S2IO_PARM_INT(rmac_util_period, 5);
471S2IO_PARM_INT(l3l4hdr_size, 128); 492S2IO_PARM_INT(l3l4hdr_size, 128);
493/* 0 is no steering, 1 is Priority steering, 2 is Default steering */
494S2IO_PARM_INT(tx_steering_type, TX_DEFAULT_STEERING);
472/* Frequency of Rx desc syncs expressed as power of 2 */ 495/* Frequency of Rx desc syncs expressed as power of 2 */
473S2IO_PARM_INT(rxsync_frequency, 3); 496S2IO_PARM_INT(rxsync_frequency, 3);
474/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ 497/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
@@ -533,6 +556,101 @@ static struct pci_driver s2io_driver = {
533/* A simplifier macro used both by init and free shared_mem Fns(). */ 556/* A simplifier macro used both by init and free shared_mem Fns(). */
534#define TXD_MEM_PAGE_CNT(len, per_each) ((len+per_each - 1) / per_each) 557#define TXD_MEM_PAGE_CNT(len, per_each) ((len+per_each - 1) / per_each)
535 558
559/* netqueue manipulation helper functions */
560static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp)
561{
562 int i;
563#ifdef CONFIG_NETDEVICES_MULTIQUEUE
564 if (sp->config.multiq) {
565 for (i = 0; i < sp->config.tx_fifo_num; i++)
566 netif_stop_subqueue(sp->dev, i);
567 } else
568#endif
569 {
570 for (i = 0; i < sp->config.tx_fifo_num; i++)
571 sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP;
572 netif_stop_queue(sp->dev);
573 }
574}
575
576static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no)
577{
578#ifdef CONFIG_NETDEVICES_MULTIQUEUE
579 if (sp->config.multiq)
580 netif_stop_subqueue(sp->dev, fifo_no);
581 else
582#endif
583 {
584 sp->mac_control.fifos[fifo_no].queue_state =
585 FIFO_QUEUE_STOP;
586 netif_stop_queue(sp->dev);
587 }
588}
589
590static inline void s2io_start_all_tx_queue(struct s2io_nic *sp)
591{
592 int i;
593#ifdef CONFIG_NETDEVICES_MULTIQUEUE
594 if (sp->config.multiq) {
595 for (i = 0; i < sp->config.tx_fifo_num; i++)
596 netif_start_subqueue(sp->dev, i);
597 } else
598#endif
599 {
600 for (i = 0; i < sp->config.tx_fifo_num; i++)
601 sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
602 netif_start_queue(sp->dev);
603 }
604}
605
606static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no)
607{
608#ifdef CONFIG_NETDEVICES_MULTIQUEUE
609 if (sp->config.multiq)
610 netif_start_subqueue(sp->dev, fifo_no);
611 else
612#endif
613 {
614 sp->mac_control.fifos[fifo_no].queue_state =
615 FIFO_QUEUE_START;
616 netif_start_queue(sp->dev);
617 }
618}
619
620static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp)
621{
622 int i;
623#ifdef CONFIG_NETDEVICES_MULTIQUEUE
624 if (sp->config.multiq) {
625 for (i = 0; i < sp->config.tx_fifo_num; i++)
626 netif_wake_subqueue(sp->dev, i);
627 } else
628#endif
629 {
630 for (i = 0; i < sp->config.tx_fifo_num; i++)
631 sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
632 netif_wake_queue(sp->dev);
633 }
634}
635
636static inline void s2io_wake_tx_queue(
637 struct fifo_info *fifo, int cnt, u8 multiq)
638{
639
640#ifdef CONFIG_NETDEVICES_MULTIQUEUE
641 if (multiq) {
642 if (cnt && __netif_subqueue_stopped(fifo->dev, fifo->fifo_no))
643 netif_wake_subqueue(fifo->dev, fifo->fifo_no);
644 } else
645#endif
646 if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) {
647 if (netif_queue_stopped(fifo->dev)) {
648 fifo->queue_state = FIFO_QUEUE_START;
649 netif_wake_queue(fifo->dev);
650 }
651 }
652}
653
536/** 654/**
537 * init_shared_mem - Allocation and Initialization of Memory 655 * init_shared_mem - Allocation and Initialization of Memory
538 * @nic: Device private variable. 656 * @nic: Device private variable.
@@ -614,6 +732,7 @@ static int init_shared_mem(struct s2io_nic *nic)
614 mac_control->fifos[i].fifo_no = i; 732 mac_control->fifos[i].fifo_no = i;
615 mac_control->fifos[i].nic = nic; 733 mac_control->fifos[i].nic = nic;
616 mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2; 734 mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2;
735 mac_control->fifos[i].dev = dev;
617 736
618 for (j = 0; j < page_num; j++) { 737 for (j = 0; j < page_num; j++) {
619 int k = 0; 738 int k = 0;
@@ -2948,7 +3067,7 @@ static void rx_intr_handler(struct ring_info *ring_data)
2948 struct lro *lro = &nic->lro0_n[i]; 3067 struct lro *lro = &nic->lro0_n[i];
2949 if (lro->in_use) { 3068 if (lro->in_use) {
2950 update_L3L4_header(nic, lro); 3069 update_L3L4_header(nic, lro);
2951 queue_rx_frame(lro->parent); 3070 queue_rx_frame(lro->parent, lro->vlan_tag);
2952 clear_lro_session(lro); 3071 clear_lro_session(lro);
2953 } 3072 }
2954 } 3073 }
@@ -2972,10 +3091,10 @@ static void rx_intr_handler(struct ring_info *ring_data)
2972static void tx_intr_handler(struct fifo_info *fifo_data) 3091static void tx_intr_handler(struct fifo_info *fifo_data)
2973{ 3092{
2974 struct s2io_nic *nic = fifo_data->nic; 3093 struct s2io_nic *nic = fifo_data->nic;
2975 struct net_device *dev = (struct net_device *) nic->dev;
2976 struct tx_curr_get_info get_info, put_info; 3094 struct tx_curr_get_info get_info, put_info;
2977 struct sk_buff *skb; 3095 struct sk_buff *skb = NULL;
2978 struct TxD *txdlp; 3096 struct TxD *txdlp;
3097 int pkt_cnt = 0;
2979 unsigned long flags = 0; 3098 unsigned long flags = 0;
2980 u8 err_mask; 3099 u8 err_mask;
2981 3100
@@ -3036,6 +3155,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
3036 DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); 3155 DBG_PRINT(ERR_DBG, "in Tx Free Intr\n");
3037 return; 3156 return;
3038 } 3157 }
3158 pkt_cnt++;
3039 3159
3040 /* Updating the statistics block */ 3160 /* Updating the statistics block */
3041 nic->stats.tx_bytes += skb->len; 3161 nic->stats.tx_bytes += skb->len;
@@ -3051,8 +3171,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
3051 get_info.offset; 3171 get_info.offset;
3052 } 3172 }
3053 3173
3054 if (netif_queue_stopped(dev)) 3174 s2io_wake_tx_queue(fifo_data, pkt_cnt, nic->config.multiq);
3055 netif_wake_queue(dev);
3056 3175
3057 spin_unlock_irqrestore(&fifo_data->tx_lock, flags); 3176 spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
3058} 3177}
@@ -3933,8 +4052,7 @@ static int s2io_open(struct net_device *dev)
3933 err = -ENODEV; 4052 err = -ENODEV;
3934 goto hw_init_failed; 4053 goto hw_init_failed;
3935 } 4054 }
3936 4055 s2io_start_all_tx_queue(sp);
3937 netif_start_queue(dev);
3938 return 0; 4056 return 0;
3939 4057
3940hw_init_failed: 4058hw_init_failed:
@@ -3979,8 +4097,7 @@ static int s2io_close(struct net_device *dev)
3979 if (!is_s2io_card_up(sp)) 4097 if (!is_s2io_card_up(sp))
3980 return 0; 4098 return 0;
3981 4099
3982 netif_stop_queue(dev); 4100 s2io_stop_all_tx_queue(sp);
3983
3984 /* delete all populated mac entries */ 4101 /* delete all populated mac entries */
3985 for (offset = 1; offset < config->max_mc_addr; offset++) { 4102 for (offset = 1; offset < config->max_mc_addr; offset++) {
3986 tmp64 = do_s2io_read_unicast_mc(sp, offset); 4103 tmp64 = do_s2io_read_unicast_mc(sp, offset);
@@ -4016,11 +4133,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
4016 struct TxFIFO_element __iomem *tx_fifo; 4133 struct TxFIFO_element __iomem *tx_fifo;
4017 unsigned long flags = 0; 4134 unsigned long flags = 0;
4018 u16 vlan_tag = 0; 4135 u16 vlan_tag = 0;
4019 int vlan_priority = 0;
4020 struct fifo_info *fifo = NULL; 4136 struct fifo_info *fifo = NULL;
4021 struct mac_info *mac_control; 4137 struct mac_info *mac_control;
4022 struct config_param *config; 4138 struct config_param *config;
4139 int do_spin_lock = 1;
4023 int offload_type; 4140 int offload_type;
4141 int enable_per_list_interrupt = 0;
4024 struct swStat *stats = &sp->mac_control.stats_info->sw_stat; 4142 struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
4025 4143
4026 mac_control = &sp->mac_control; 4144 mac_control = &sp->mac_control;
@@ -4042,15 +4160,67 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
4042 } 4160 }
4043 4161
4044 queue = 0; 4162 queue = 0;
4045 /* Get Fifo number to Transmit based on vlan priority */ 4163 if (sp->vlgrp && vlan_tx_tag_present(skb))
4046 if (sp->vlgrp && vlan_tx_tag_present(skb)) {
4047 vlan_tag = vlan_tx_tag_get(skb); 4164 vlan_tag = vlan_tx_tag_get(skb);
4048 vlan_priority = vlan_tag >> 13; 4165 if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) {
4049 queue = config->fifo_mapping[vlan_priority]; 4166 if (skb->protocol == htons(ETH_P_IP)) {
4167 struct iphdr *ip;
4168 struct tcphdr *th;
4169 ip = ip_hdr(skb);
4170
4171 if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) {
4172 th = (struct tcphdr *)(((unsigned char *)ip) +
4173 ip->ihl*4);
4174
4175 if (ip->protocol == IPPROTO_TCP) {
4176 queue_len = sp->total_tcp_fifos;
4177 queue = (ntohs(th->source) +
4178 ntohs(th->dest)) &
4179 sp->fifo_selector[queue_len - 1];
4180 if (queue >= queue_len)
4181 queue = queue_len - 1;
4182 } else if (ip->protocol == IPPROTO_UDP) {
4183 queue_len = sp->total_udp_fifos;
4184 queue = (ntohs(th->source) +
4185 ntohs(th->dest)) &
4186 sp->fifo_selector[queue_len - 1];
4187 if (queue >= queue_len)
4188 queue = queue_len - 1;
4189 queue += sp->udp_fifo_idx;
4190 if (skb->len > 1024)
4191 enable_per_list_interrupt = 1;
4192 do_spin_lock = 0;
4193 }
4194 }
4195 }
4196 } else if (sp->config.tx_steering_type == TX_PRIORITY_STEERING)
4197 /* get fifo number based on skb->priority value */
4198 queue = config->fifo_mapping
4199 [skb->priority & (MAX_TX_FIFOS - 1)];
4200 fifo = &mac_control->fifos[queue];
4201
4202 if (do_spin_lock)
4203 spin_lock_irqsave(&fifo->tx_lock, flags);
4204 else {
4205 if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags)))
4206 return NETDEV_TX_LOCKED;
4207 }
4208
4209#ifdef CONFIG_NETDEVICES_MULTIQUEUE
4210 if (sp->config.multiq) {
4211 if (__netif_subqueue_stopped(dev, fifo->fifo_no)) {
4212 spin_unlock_irqrestore(&fifo->tx_lock, flags);
4213 return NETDEV_TX_BUSY;
4214 }
4215 } else
4216#endif
4217 if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) {
4218 if (netif_queue_stopped(dev)) {
4219 spin_unlock_irqrestore(&fifo->tx_lock, flags);
4220 return NETDEV_TX_BUSY;
4221 }
4050 } 4222 }
4051 4223
4052 fifo = &mac_control->fifos[queue];
4053 spin_lock_irqsave(&fifo->tx_lock, flags);
4054 put_off = (u16) fifo->tx_curr_put_info.offset; 4224 put_off = (u16) fifo->tx_curr_put_info.offset;
4055 get_off = (u16) fifo->tx_curr_get_info.offset; 4225 get_off = (u16) fifo->tx_curr_get_info.offset;
4056 txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr; 4226 txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr;
@@ -4060,7 +4230,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
4060 if (txdp->Host_Control || 4230 if (txdp->Host_Control ||
4061 ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { 4231 ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
4062 DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); 4232 DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n");
4063 netif_stop_queue(dev); 4233 s2io_stop_tx_queue(sp, fifo->fifo_no);
4064 dev_kfree_skb(skb); 4234 dev_kfree_skb(skb);
4065 spin_unlock_irqrestore(&fifo->tx_lock, flags); 4235 spin_unlock_irqrestore(&fifo->tx_lock, flags);
4066 return 0; 4236 return 0;
@@ -4079,8 +4249,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
4079 txdp->Control_1 |= TXD_GATHER_CODE_FIRST; 4249 txdp->Control_1 |= TXD_GATHER_CODE_FIRST;
4080 txdp->Control_1 |= TXD_LIST_OWN_XENA; 4250 txdp->Control_1 |= TXD_LIST_OWN_XENA;
4081 txdp->Control_2 |= TXD_INT_NUMBER(fifo->fifo_no); 4251 txdp->Control_2 |= TXD_INT_NUMBER(fifo->fifo_no);
4082 4252 if (enable_per_list_interrupt)
4083 if (sp->vlgrp && vlan_tx_tag_present(skb)) { 4253 if (put_off & (queue_len >> 5))
4254 txdp->Control_2 |= TXD_INT_TYPE_PER_LIST;
4255 if (vlan_tag) {
4084 txdp->Control_2 |= TXD_VLAN_ENABLE; 4256 txdp->Control_2 |= TXD_VLAN_ENABLE;
4085 txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag); 4257 txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
4086 } 4258 }
@@ -4166,7 +4338,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
4166 DBG_PRINT(TX_DBG, 4338 DBG_PRINT(TX_DBG,
4167 "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", 4339 "No free TxDs for xmit, Put: 0x%x Get:0x%x\n",
4168 put_off, get_off); 4340 put_off, get_off);
4169 netif_stop_queue(dev); 4341 s2io_stop_tx_queue(sp, fifo->fifo_no);
4170 } 4342 }
4171 mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; 4343 mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
4172 dev->trans_start = jiffies; 4344 dev->trans_start = jiffies;
@@ -4175,7 +4347,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
4175 return 0; 4347 return 0;
4176pci_map_failed: 4348pci_map_failed:
4177 stats->pci_map_fail_cnt++; 4349 stats->pci_map_fail_cnt++;
4178 netif_stop_queue(dev); 4350 s2io_stop_tx_queue(sp, fifo->fifo_no);
4179 stats->mem_freed += skb->truesize; 4351 stats->mem_freed += skb->truesize;
4180 dev_kfree_skb(skb); 4352 dev_kfree_skb(skb);
4181 spin_unlock_irqrestore(&fifo->tx_lock, flags); 4353 spin_unlock_irqrestore(&fifo->tx_lock, flags);
@@ -4587,7 +4759,7 @@ static void s2io_handle_errors(void * dev_id)
4587 return; 4759 return;
4588 4760
4589reset: 4761reset:
4590 netif_stop_queue(dev); 4762 s2io_stop_all_tx_queue(sp);
4591 schedule_work(&sp->rst_timer_task); 4763 schedule_work(&sp->rst_timer_task);
4592 sw_stat->soft_reset_cnt++; 4764 sw_stat->soft_reset_cnt++;
4593 return; 4765 return;
@@ -6574,16 +6746,15 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu)
6574 6746
6575 dev->mtu = new_mtu; 6747 dev->mtu = new_mtu;
6576 if (netif_running(dev)) { 6748 if (netif_running(dev)) {
6749 s2io_stop_all_tx_queue(sp);
6577 s2io_card_down(sp); 6750 s2io_card_down(sp);
6578 netif_stop_queue(dev);
6579 ret = s2io_card_up(sp); 6751 ret = s2io_card_up(sp);
6580 if (ret) { 6752 if (ret) {
6581 DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", 6753 DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
6582 __FUNCTION__); 6754 __FUNCTION__);
6583 return ret; 6755 return ret;
6584 } 6756 }
6585 if (netif_queue_stopped(dev)) 6757 s2io_wake_all_tx_queue(sp);
6586 netif_wake_queue(dev);
6587 } else { /* Device is down */ 6758 } else { /* Device is down */
6588 struct XENA_dev_config __iomem *bar0 = sp->bar0; 6759 struct XENA_dev_config __iomem *bar0 = sp->bar0;
6589 u64 val64 = new_mtu; 6760 u64 val64 = new_mtu;
@@ -6691,7 +6862,7 @@ static void s2io_set_link(struct work_struct *work)
6691 } else { 6862 } else {
6692 DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); 6863 DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name);
6693 DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); 6864 DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
6694 netif_stop_queue(dev); 6865 s2io_stop_all_tx_queue(nic);
6695 } 6866 }
6696 } 6867 }
6697 val64 = readq(&bar0->adapter_control); 6868 val64 = readq(&bar0->adapter_control);
@@ -7181,7 +7352,7 @@ static void s2io_restart_nic(struct work_struct *work)
7181 DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", 7352 DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
7182 dev->name); 7353 dev->name);
7183 } 7354 }
7184 netif_wake_queue(dev); 7355 s2io_wake_all_tx_queue(sp);
7185 DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", 7356 DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n",
7186 dev->name); 7357 dev->name);
7187out_unlock: 7358out_unlock:
@@ -7371,7 +7542,8 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
7371 { 7542 {
7372 lro_append_pkt(sp, lro, 7543 lro_append_pkt(sp, lro,
7373 skb, tcp_len); 7544 skb, tcp_len);
7374 queue_rx_frame(lro->parent); 7545 queue_rx_frame(lro->parent,
7546 lro->vlan_tag);
7375 clear_lro_session(lro); 7547 clear_lro_session(lro);
7376 sp->mac_control.stats_info-> 7548 sp->mac_control.stats_info->
7377 sw_stat.flush_max_pkts++; 7549 sw_stat.flush_max_pkts++;
@@ -7382,7 +7554,8 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
7382 lro->frags_len; 7554 lro->frags_len;
7383 sp->mac_control.stats_info-> 7555 sp->mac_control.stats_info->
7384 sw_stat.sending_both++; 7556 sw_stat.sending_both++;
7385 queue_rx_frame(lro->parent); 7557 queue_rx_frame(lro->parent,
7558 lro->vlan_tag);
7386 clear_lro_session(lro); 7559 clear_lro_session(lro);
7387 goto send_up; 7560 goto send_up;
7388 case 0: /* sessions exceeded */ 7561 case 0: /* sessions exceeded */
@@ -7408,31 +7581,12 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
7408 */ 7581 */
7409 skb->ip_summed = CHECKSUM_NONE; 7582 skb->ip_summed = CHECKSUM_NONE;
7410 } 7583 }
7411 } else { 7584 } else
7412 skb->ip_summed = CHECKSUM_NONE; 7585 skb->ip_summed = CHECKSUM_NONE;
7413 } 7586
7414 sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; 7587 sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
7415 if (!sp->lro) {
7416 skb->protocol = eth_type_trans(skb, dev);
7417 if ((sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2) &&
7418 vlan_strip_flag)) {
7419 /* Queueing the vlan frame to the upper layer */
7420 if (napi)
7421 vlan_hwaccel_receive_skb(skb, sp->vlgrp,
7422 RXD_GET_VLAN_TAG(rxdp->Control_2));
7423 else
7424 vlan_hwaccel_rx(skb, sp->vlgrp,
7425 RXD_GET_VLAN_TAG(rxdp->Control_2));
7426 } else {
7427 if (napi)
7428 netif_receive_skb(skb);
7429 else
7430 netif_rx(skb);
7431 }
7432 } else {
7433send_up: 7588send_up:
7434 queue_rx_frame(skb); 7589 queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
7435 }
7436 dev->last_rx = jiffies; 7590 dev->last_rx = jiffies;
7437aggregate: 7591aggregate:
7438 atomic_dec(&sp->rx_bufs_left[ring_no]); 7592 atomic_dec(&sp->rx_bufs_left[ring_no]);
@@ -7460,6 +7614,7 @@ static void s2io_link(struct s2io_nic * sp, int link)
7460 init_tti(sp, link); 7614 init_tti(sp, link);
7461 if (link == LINK_DOWN) { 7615 if (link == LINK_DOWN) {
7462 DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); 7616 DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
7617 s2io_stop_all_tx_queue(sp);
7463 netif_carrier_off(dev); 7618 netif_carrier_off(dev);
7464 if(sp->mac_control.stats_info->sw_stat.link_up_cnt) 7619 if(sp->mac_control.stats_info->sw_stat.link_up_cnt)
7465 sp->mac_control.stats_info->sw_stat.link_up_time = 7620 sp->mac_control.stats_info->sw_stat.link_up_time =
@@ -7472,6 +7627,7 @@ static void s2io_link(struct s2io_nic * sp, int link)
7472 jiffies - sp->start_time; 7627 jiffies - sp->start_time;
7473 sp->mac_control.stats_info->sw_stat.link_up_cnt++; 7628 sp->mac_control.stats_info->sw_stat.link_up_cnt++;
7474 netif_carrier_on(dev); 7629 netif_carrier_on(dev);
7630 s2io_wake_all_tx_queue(sp);
7475 } 7631 }
7476 } 7632 }
7477 sp->last_link_state = link; 7633 sp->last_link_state = link;
@@ -7508,20 +7664,48 @@ static void s2io_init_pci(struct s2io_nic * sp)
7508 pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); 7664 pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
7509} 7665}
7510 7666
7511static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) 7667static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
7668 u8 *dev_multiq)
7512{ 7669{
7513 if ((tx_fifo_num > MAX_TX_FIFOS) || 7670 if ((tx_fifo_num > MAX_TX_FIFOS) ||
7514 (tx_fifo_num < FIFO_DEFAULT_NUM)) { 7671 (tx_fifo_num < 1)) {
7515 DBG_PRINT(ERR_DBG, "s2io: Requested number of tx fifos " 7672 DBG_PRINT(ERR_DBG, "s2io: Requested number of tx fifos "
7516 "(%d) not supported\n", tx_fifo_num); 7673 "(%d) not supported\n", tx_fifo_num);
7517 tx_fifo_num = 7674
7518 ((tx_fifo_num > MAX_TX_FIFOS)? MAX_TX_FIFOS : 7675 if (tx_fifo_num < 1)
7519 ((tx_fifo_num < FIFO_DEFAULT_NUM) ? FIFO_DEFAULT_NUM : 7676 tx_fifo_num = 1;
7520 tx_fifo_num)); 7677 else
7678 tx_fifo_num = MAX_TX_FIFOS;
7679
7521 DBG_PRINT(ERR_DBG, "s2io: Default to %d ", tx_fifo_num); 7680 DBG_PRINT(ERR_DBG, "s2io: Default to %d ", tx_fifo_num);
7522 DBG_PRINT(ERR_DBG, "tx fifos\n"); 7681 DBG_PRINT(ERR_DBG, "tx fifos\n");
7523 } 7682 }
7524 7683
7684#ifndef CONFIG_NETDEVICES_MULTIQUEUE
7685 if (multiq) {
7686 DBG_PRINT(ERR_DBG, "s2io: Multiqueue support not enabled\n");
7687 multiq = 0;
7688 }
7689#endif
7690 if (multiq)
7691 *dev_multiq = multiq;
7692
7693 if (tx_steering_type && (1 == tx_fifo_num)) {
7694 if (tx_steering_type != TX_DEFAULT_STEERING)
7695 DBG_PRINT(ERR_DBG,
7696 "s2io: Tx steering is not supported with "
7697 "one fifo. Disabling Tx steering.\n");
7698 tx_steering_type = NO_STEERING;
7699 }
7700
7701 if ((tx_steering_type < NO_STEERING) ||
7702 (tx_steering_type > TX_DEFAULT_STEERING)) {
7703 DBG_PRINT(ERR_DBG, "s2io: Requested transmit steering not "
7704 "supported\n");
7705 DBG_PRINT(ERR_DBG, "s2io: Disabling transmit steering\n");
7706 tx_steering_type = NO_STEERING;
7707 }
7708
7525 if ( rx_ring_num > 8) { 7709 if ( rx_ring_num > 8) {
7526 DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not " 7710 DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not "
7527 "supported\n"); 7711 "supported\n");
@@ -7613,9 +7797,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7613 struct config_param *config; 7797 struct config_param *config;
7614 int mode; 7798 int mode;
7615 u8 dev_intr_type = intr_type; 7799 u8 dev_intr_type = intr_type;
7800 u8 dev_multiq = 0;
7616 DECLARE_MAC_BUF(mac); 7801 DECLARE_MAC_BUF(mac);
7617 7802
7618 if ((ret = s2io_verify_parm(pdev, &dev_intr_type))) 7803 ret = s2io_verify_parm(pdev, &dev_intr_type, &dev_multiq);
7804 if (ret)
7619 return ret; 7805 return ret;
7620 7806
7621 if ((ret = pci_enable_device(pdev))) { 7807 if ((ret = pci_enable_device(pdev))) {
@@ -7646,7 +7832,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7646 pci_disable_device(pdev); 7832 pci_disable_device(pdev);
7647 return -ENODEV; 7833 return -ENODEV;
7648 } 7834 }
7649 7835#ifdef CONFIG_NETDEVICES_MULTIQUEUE
7836 if (dev_multiq)
7837 dev = alloc_etherdev_mq(sizeof(struct s2io_nic), tx_fifo_num);
7838 else
7839#endif
7650 dev = alloc_etherdev(sizeof(struct s2io_nic)); 7840 dev = alloc_etherdev(sizeof(struct s2io_nic));
7651 if (dev == NULL) { 7841 if (dev == NULL) {
7652 DBG_PRINT(ERR_DBG, "Device allocation failed\n"); 7842 DBG_PRINT(ERR_DBG, "Device allocation failed\n");
@@ -7695,17 +7885,45 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7695 config = &sp->config; 7885 config = &sp->config;
7696 7886
7697 config->napi = napi; 7887 config->napi = napi;
7888 config->tx_steering_type = tx_steering_type;
7698 7889
7699 /* Tx side parameters. */ 7890 /* Tx side parameters. */
7700 config->tx_fifo_num = tx_fifo_num; 7891 if (config->tx_steering_type == TX_PRIORITY_STEERING)
7701 for (i = 0; i < MAX_TX_FIFOS; i++) { 7892 config->tx_fifo_num = MAX_TX_FIFOS;
7893 else
7894 config->tx_fifo_num = tx_fifo_num;
7895
7896 /* Initialize the fifos used for tx steering */
7897 if (config->tx_fifo_num < 5) {
7898 if (config->tx_fifo_num == 1)
7899 sp->total_tcp_fifos = 1;
7900 else
7901 sp->total_tcp_fifos = config->tx_fifo_num - 1;
7902 sp->udp_fifo_idx = config->tx_fifo_num - 1;
7903 sp->total_udp_fifos = 1;
7904 sp->other_fifo_idx = sp->total_tcp_fifos - 1;
7905 } else {
7906 sp->total_tcp_fifos = (tx_fifo_num - FIFO_UDP_MAX_NUM -
7907 FIFO_OTHER_MAX_NUM);
7908 sp->udp_fifo_idx = sp->total_tcp_fifos;
7909 sp->total_udp_fifos = FIFO_UDP_MAX_NUM;
7910 sp->other_fifo_idx = sp->udp_fifo_idx + FIFO_UDP_MAX_NUM;
7911 }
7912
7913 config->multiq = dev_multiq;
7914 for (i = 0; i < config->tx_fifo_num; i++) {
7702 config->tx_cfg[i].fifo_len = tx_fifo_len[i]; 7915 config->tx_cfg[i].fifo_len = tx_fifo_len[i];
7703 config->tx_cfg[i].fifo_priority = i; 7916 config->tx_cfg[i].fifo_priority = i;
7704 } 7917 }
7705 7918
7706 /* mapping the QoS priority to the configured fifos */ 7919 /* mapping the QoS priority to the configured fifos */
7707 for (i = 0; i < MAX_TX_FIFOS; i++) 7920 for (i = 0; i < MAX_TX_FIFOS; i++)
7708 config->fifo_mapping[i] = fifo_map[config->tx_fifo_num][i]; 7921 config->fifo_mapping[i] = fifo_map[config->tx_fifo_num - 1][i];
7922
7923 /* map the hashing selector table to the configured fifos */
7924 for (i = 0; i < config->tx_fifo_num; i++)
7925 sp->fifo_selector[i] = fifo_selector[i];
7926
7709 7927
7710 config->tx_intr_type = TXD_INT_TYPE_UTILZ; 7928 config->tx_intr_type = TXD_INT_TYPE_UTILZ;
7711 for (i = 0; i < config->tx_fifo_num; i++) { 7929 for (i = 0; i < config->tx_fifo_num; i++) {
@@ -7790,6 +8008,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7790 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 8008 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
7791 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 8009 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
7792 dev->vlan_rx_register = s2io_vlan_rx_register; 8010 dev->vlan_rx_register = s2io_vlan_rx_register;
8011 dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid;
7793 8012
7794 /* 8013 /*
7795 * will use eth_mac_addr() for dev->set_mac_address 8014 * will use eth_mac_addr() for dev->set_mac_address
@@ -7810,7 +8029,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7810 dev->features |= NETIF_F_UFO; 8029 dev->features |= NETIF_F_UFO;
7811 dev->features |= NETIF_F_HW_CSUM; 8030 dev->features |= NETIF_F_HW_CSUM;
7812 } 8031 }
7813 8032#ifdef CONFIG_NETDEVICES_MULTIQUEUE
8033 if (config->multiq)
8034 dev->features |= NETIF_F_MULTI_QUEUE;
8035#endif
7814 dev->tx_timeout = &s2io_tx_watchdog; 8036 dev->tx_timeout = &s2io_tx_watchdog;
7815 dev->watchdog_timeo = WATCH_DOG_TIMEOUT; 8037 dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
7816 INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); 8038 INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
@@ -7959,6 +8181,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7959 8181
7960 if (napi) 8182 if (napi)
7961 DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); 8183 DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name);
8184
8185 DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name,
8186 sp->config.tx_fifo_num);
8187
7962 switch(sp->config.intr_type) { 8188 switch(sp->config.intr_type) {
7963 case INTA: 8189 case INTA:
7964 DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); 8190 DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
@@ -7967,6 +8193,29 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7967 DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); 8193 DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
7968 break; 8194 break;
7969 } 8195 }
8196 if (sp->config.multiq) {
8197 for (i = 0; i < sp->config.tx_fifo_num; i++)
8198 mac_control->fifos[i].multiq = config->multiq;
8199 DBG_PRINT(ERR_DBG, "%s: Multiqueue support enabled\n",
8200 dev->name);
8201 } else
8202 DBG_PRINT(ERR_DBG, "%s: Multiqueue support disabled\n",
8203 dev->name);
8204
8205 switch (sp->config.tx_steering_type) {
8206 case NO_STEERING:
8207 DBG_PRINT(ERR_DBG, "%s: No steering enabled for"
8208 " transmit\n", dev->name);
8209 break;
8210 case TX_PRIORITY_STEERING:
8211 DBG_PRINT(ERR_DBG, "%s: Priority steering enabled for"
8212 " transmit\n", dev->name);
8213 break;
8214 case TX_DEFAULT_STEERING:
8215 DBG_PRINT(ERR_DBG, "%s: Default steering enabled for"
8216 " transmit\n", dev->name);
8217 }
8218
7970 if (sp->lro) 8219 if (sp->lro)
7971 DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", 8220 DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
7972 dev->name); 8221 dev->name);
@@ -8061,7 +8310,8 @@ module_init(s2io_starter);
8061module_exit(s2io_closer); 8310module_exit(s2io_closer);
8062 8311
8063static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, 8312static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
8064 struct tcphdr **tcp, struct RxD_t *rxdp) 8313 struct tcphdr **tcp, struct RxD_t *rxdp,
8314 struct s2io_nic *sp)
8065{ 8315{
8066 int ip_off; 8316 int ip_off;
8067 u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len; 8317 u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len;
@@ -8072,19 +8322,20 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
8072 return -1; 8322 return -1;
8073 } 8323 }
8074 8324
8075 /* TODO: 8325 /* Checking for DIX type or DIX type with VLAN */
8076 * By default the VLAN field in the MAC is stripped by the card, if this 8326 if ((l2_type == 0)
8077 * feature is turned off in rx_pa_cfg register, then the ip_off field 8327 || (l2_type == 4)) {
8078 * has to be shifted by a further 2 bytes 8328 ip_off = HEADER_ETHERNET_II_802_3_SIZE;
8079 */ 8329 /*
8080 switch (l2_type) { 8330 * If vlan stripping is disabled and the frame is VLAN tagged,
8081 case 0: /* DIX type */ 8331 * shift the offset by the VLAN header size bytes.
8082 case 4: /* DIX type with VLAN */ 8332 */
8083 ip_off = HEADER_ETHERNET_II_802_3_SIZE; 8333 if ((!vlan_strip_flag) &&
8084 break; 8334 (rxdp->Control_1 & RXD_FRAME_VLAN_TAG))
8335 ip_off += HEADER_VLAN_SIZE;
8336 } else {
8085 /* LLC, SNAP etc are considered non-mergeable */ 8337 /* LLC, SNAP etc are considered non-mergeable */
8086 default: 8338 return -1;
8087 return -1;
8088 } 8339 }
8089 8340
8090 *ip = (struct iphdr *)((u8 *)buffer + ip_off); 8341 *ip = (struct iphdr *)((u8 *)buffer + ip_off);
@@ -8111,7 +8362,7 @@ static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp)
8111} 8362}
8112 8363
8113static void initiate_new_session(struct lro *lro, u8 *l2h, 8364static void initiate_new_session(struct lro *lro, u8 *l2h,
8114 struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) 8365 struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag)
8115{ 8366{
8116 DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); 8367 DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
8117 lro->l2h = l2h; 8368 lro->l2h = l2h;
@@ -8122,6 +8373,7 @@ static void initiate_new_session(struct lro *lro, u8 *l2h,
8122 lro->sg_num = 1; 8373 lro->sg_num = 1;
8123 lro->total_len = ntohs(ip->tot_len); 8374 lro->total_len = ntohs(ip->tot_len);
8124 lro->frags_len = 0; 8375 lro->frags_len = 0;
8376 lro->vlan_tag = vlan_tag;
8125 /* 8377 /*
8126 * check if we saw TCP timestamp. Other consistency checks have 8378 * check if we saw TCP timestamp. Other consistency checks have
8127 * already been done. 8379 * already been done.
@@ -8253,15 +8505,16 @@ s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro,
8253 struct iphdr *ip; 8505 struct iphdr *ip;
8254 struct tcphdr *tcph; 8506 struct tcphdr *tcph;
8255 int ret = 0, i; 8507 int ret = 0, i;
8508 u16 vlan_tag = 0;
8256 8509
8257 if (!(ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp, 8510 if (!(ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp,
8258 rxdp))) { 8511 rxdp, sp))) {
8259 DBG_PRINT(INFO_DBG,"IP Saddr: %x Daddr: %x\n", 8512 DBG_PRINT(INFO_DBG,"IP Saddr: %x Daddr: %x\n",
8260 ip->saddr, ip->daddr); 8513 ip->saddr, ip->daddr);
8261 } else { 8514 } else
8262 return ret; 8515 return ret;
8263 }
8264 8516
8517 vlan_tag = RXD_GET_VLAN_TAG(rxdp->Control_2);
8265 tcph = (struct tcphdr *)*tcp; 8518 tcph = (struct tcphdr *)*tcp;
8266 *tcp_len = get_l4_pyld_length(ip, tcph); 8519 *tcp_len = get_l4_pyld_length(ip, tcph);
8267 for (i=0; i<MAX_LRO_SESSIONS; i++) { 8520 for (i=0; i<MAX_LRO_SESSIONS; i++) {
@@ -8321,7 +8574,8 @@ s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro,
8321 8574
8322 switch (ret) { 8575 switch (ret) {
8323 case 3: 8576 case 3:
8324 initiate_new_session(*lro, buffer, ip, tcph, *tcp_len); 8577 initiate_new_session(*lro, buffer, ip, tcph, *tcp_len,
8578 vlan_tag);
8325 break; 8579 break;
8326 case 2: 8580 case 2:
8327 update_L3L4_header(sp, *lro); 8581 update_L3L4_header(sp, *lro);
@@ -8349,15 +8603,25 @@ static void clear_lro_session(struct lro *lro)
8349 memset(lro, 0, lro_struct_size); 8603 memset(lro, 0, lro_struct_size);
8350} 8604}
8351 8605
8352static void queue_rx_frame(struct sk_buff *skb) 8606static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
8353{ 8607{
8354 struct net_device *dev = skb->dev; 8608 struct net_device *dev = skb->dev;
8609 struct s2io_nic *sp = dev->priv;
8355 8610
8356 skb->protocol = eth_type_trans(skb, dev); 8611 skb->protocol = eth_type_trans(skb, dev);
8357 if (napi) 8612 if (sp->vlgrp && vlan_tag
8358 netif_receive_skb(skb); 8613 && (vlan_strip_flag)) {
8359 else 8614 /* Queueing the vlan frame to the upper layer */
8360 netif_rx(skb); 8615 if (sp->config.napi)
8616 vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag);
8617 else
8618 vlan_hwaccel_rx(skb, sp->vlgrp, vlan_tag);
8619 } else {
8620 if (sp->config.napi)
8621 netif_receive_skb(skb);
8622 else
8623 netif_rx(skb);
8624 }
8361} 8625}
8362 8626
8363static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, 8627static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 64b88eb48287..e68fdf7e4260 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -360,7 +360,10 @@ struct stat_block {
360#define MAX_TX_FIFOS 8 360#define MAX_TX_FIFOS 8
361#define MAX_RX_RINGS 8 361#define MAX_RX_RINGS 8
362 362
363#define FIFO_DEFAULT_NUM 1 363#define FIFO_DEFAULT_NUM 5
364#define FIFO_UDP_MAX_NUM 2 /* 0 - even, 1 -odd ports */
365#define FIFO_OTHER_MAX_NUM 1
366
364 367
365#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) 368#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 )
366#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) 369#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
@@ -379,6 +382,8 @@ static int fifo_map[][MAX_TX_FIFOS] = {
379 {0, 1, 2, 3, 4, 5, 6, 7}, 382 {0, 1, 2, 3, 4, 5, 6, 7},
380}; 383};
381 384
385static u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7};
386
382/* Maintains Per FIFO related information. */ 387/* Maintains Per FIFO related information. */
383struct tx_fifo_config { 388struct tx_fifo_config {
384#define MAX_AVAILABLE_TXDS 8192 389#define MAX_AVAILABLE_TXDS 8192
@@ -431,6 +436,12 @@ struct config_param {
431/* Tx Side */ 436/* Tx Side */
432 u32 tx_fifo_num; /*Number of Tx FIFOs */ 437 u32 tx_fifo_num; /*Number of Tx FIFOs */
433 438
439 /* 0-No steering, 1-Priority steering, 2-Default fifo map */
440#define NO_STEERING 0
441#define TX_PRIORITY_STEERING 0x1
442#define TX_DEFAULT_STEERING 0x2
443 u8 tx_steering_type;
444
434 u8 fifo_mapping[MAX_TX_FIFOS]; 445 u8 fifo_mapping[MAX_TX_FIFOS];
435 struct tx_fifo_config tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ 446 struct tx_fifo_config tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */
436 u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ 447 u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */
@@ -464,6 +475,7 @@ struct config_param {
464 int max_mc_addr; /* xena=64 herc=256 */ 475 int max_mc_addr; /* xena=64 herc=256 */
465 int max_mac_addr; /* xena=16 herc=64 */ 476 int max_mac_addr; /* xena=16 herc=64 */
466 int mc_start_offset; /* xena=16 herc=64 */ 477 int mc_start_offset; /* xena=16 herc=64 */
478 u8 multiq;
467}; 479};
468 480
469/* Structure representing MAC Addrs */ 481/* Structure representing MAC Addrs */
@@ -534,6 +546,7 @@ struct RxD_t {
534#define RXD_OWN_XENA s2BIT(7) 546#define RXD_OWN_XENA s2BIT(7)
535#define RXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15)) 547#define RXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
536#define RXD_FRAME_PROTO vBIT(0xFFFF,24,8) 548#define RXD_FRAME_PROTO vBIT(0xFFFF,24,8)
549#define RXD_FRAME_VLAN_TAG s2BIT(24)
537#define RXD_FRAME_PROTO_IPV4 s2BIT(27) 550#define RXD_FRAME_PROTO_IPV4 s2BIT(27)
538#define RXD_FRAME_PROTO_IPV6 s2BIT(28) 551#define RXD_FRAME_PROTO_IPV6 s2BIT(28)
539#define RXD_FRAME_IP_FRAG s2BIT(29) 552#define RXD_FRAME_IP_FRAG s2BIT(29)
@@ -720,6 +733,15 @@ struct fifo_info {
720 * the buffers 733 * the buffers
721 */ 734 */
722 struct tx_curr_get_info tx_curr_get_info; 735 struct tx_curr_get_info tx_curr_get_info;
736#define FIFO_QUEUE_START 0
737#define FIFO_QUEUE_STOP 1
738 int queue_state;
739
740 /* copy of sp->dev pointer */
741 struct net_device *dev;
742
743 /* copy of multiq status */
744 u8 multiq;
723 745
724 /* Per fifo lock */ 746 /* Per fifo lock */
725 spinlock_t tx_lock; 747 spinlock_t tx_lock;
@@ -808,10 +830,11 @@ struct lro {
808 int sg_num; 830 int sg_num;
809 int in_use; 831 int in_use;
810 __be16 window; 832 __be16 window;
833 u16 vlan_tag;
811 u32 cur_tsval; 834 u32 cur_tsval;
812 __be32 cur_tsecr; 835 __be32 cur_tsecr;
813 u8 saw_ts; 836 u8 saw_ts;
814}; 837} ____cacheline_aligned;
815 838
816/* These flags represent the devices temporary state */ 839/* These flags represent the devices temporary state */
817enum s2io_device_state_t 840enum s2io_device_state_t
@@ -885,6 +908,27 @@ struct s2io_nic {
885 */ 908 */
886 int rx_csum; 909 int rx_csum;
887 910
911 /* Below variables are used for fifo selection to transmit a packet */
912 u16 fifo_selector[MAX_TX_FIFOS];
913
914 /* Total fifos for tcp packets */
915 u8 total_tcp_fifos;
916
917 /*
918 * Beginning index of udp for udp packets
919 * Value will be equal to
920 * (tx_fifo_num - FIFO_UDP_MAX_NUM - FIFO_OTHER_MAX_NUM)
921 */
922 u8 udp_fifo_idx;
923
924 u8 total_udp_fifos;
925
926 /*
927 * Beginning index of fifo for all other packets
928 * Value will be equal to (tx_fifo_num - FIFO_OTHER_MAX_NUM)
929 */
930 u8 other_fifo_idx;
931
888 /* after blink, the adapter must be restored with original 932 /* after blink, the adapter must be restored with original
889 * values. 933 * values.
890 */ 934 */
@@ -1087,7 +1131,7 @@ static int
1087s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, 1131s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro,
1088 struct RxD_t *rxdp, struct s2io_nic *sp); 1132 struct RxD_t *rxdp, struct s2io_nic *sp);
1089static void clear_lro_session(struct lro *lro); 1133static void clear_lro_session(struct lro *lro);
1090static void queue_rx_frame(struct sk_buff *skb); 1134static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag);
1091static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro); 1135static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro);
1092static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, 1136static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
1093 struct sk_buff *skb, u32 tcp_len); 1137 struct sk_buff *skb, u32 tcp_len);
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
deleted file mode 100644
index afd900d5d730..000000000000
--- a/drivers/net/sk98lin/Makefile
+++ /dev/null
@@ -1,87 +0,0 @@
1#
2# Makefile for the SysKonnect SK-98xx device driver.
3#
4
5
6#
7# Standalone driver params
8# SKPARAM += -DSK_KERNEL_24
9# SKPARAM += -DSK_KERNEL_24_26
10# SKPARAM += -DSK_KERNEL_26
11# SKPARAM += -DSK_KERNEL_22_24
12
13obj-$(CONFIG_SK98LIN) += sk98lin.o
14sk98lin-objs := \
15 skge.o \
16 skethtool.o \
17 skdim.o \
18 skaddr.o \
19 skgehwt.o \
20 skgeinit.o \
21 skgepnmi.o \
22 skgesirq.o \
23 ski2c.o \
24 sklm80.o \
25 skqueue.o \
26 skrlmt.o \
27 sktimer.o \
28 skvpd.o \
29 skxmac2.o
30
31# DBGDEF = \
32# -DDEBUG
33
34ifdef DEBUG
35DBGDEF += \
36-DSK_DEBUG_CHKMOD=0x00000000L \
37-DSK_DEBUG_CHKCAT=0x00000000L
38endif
39
40
41# **** possible debug modules for SK_DEBUG_CHKMOD *****************
42# SK_DBGMOD_MERR 0x00000001L /* general module error indication */
43# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
44# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
45# SK_DBGMOD_VPD 0x00000008L /* VPD module */
46# SK_DBGMOD_I2C 0x00000010L /* I2C module */
47# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
48# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
49# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
50# SK_DBGMOD_DRV 0x00010000L /* DRV module */
51
52# **** possible debug categories for SK_DEBUG_CHKCAT **************
53# *** common modules ***
54# SK_DBGCAT_INIT 0x00000001L module/driver initialization
55# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL)
56# SK_DBGCAT_ERR 0x00000004L error handling paths
57# SK_DBGCAT_TX 0x00000008L transmit path
58# SK_DBGCAT_RX 0x00000010L receive path
59# SK_DBGCAT_IRQ 0x00000020L general IRQ handling
60# SK_DBGCAT_QUEUE 0x00000040L any queue management
61# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump
62# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump
63
64# *** driver (file skge.c) ***
65# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points
66# SK_DBGCAT_DRV_??? 0x00020000 not used
67# SK_DBGCAT_DRV_MCA 0x00040000 multicast
68# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path
69# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path
70# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime
71# SK_DBGCAT_DRV_??? 0x00400000 not used
72# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode
73# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames
74# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions
75# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources
76# SK_DBGCAT_DRV_EVENT 0x08000000 driver events
77
78EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
79
80clean:
81 rm -f core *.o *.a *.s
82
83
84
85
86
87
diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
deleted file mode 100644
index 4e2dbbf78000..000000000000
--- a/drivers/net/sk98lin/h/lm80.h
+++ /dev/null
@@ -1,179 +0,0 @@
1/******************************************************************************
2 *
3 * Name: lm80.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.6 $
6 * Date: $Date: 2003/05/13 17:26:52 $
7 * Purpose: Contains all defines for the LM80 Chip
8 * (National Semiconductor).
9 *
10 ******************************************************************************/
11
12/******************************************************************************
13 *
14 * (C)Copyright 1998-2002 SysKonnect.
15 * (C)Copyright 2002-2003 Marvell.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * The information in this file is provided "AS IS" without warranty.
23 *
24 ******************************************************************************/
25
26#ifndef __INC_LM80_H
27#define __INC_LM80_H
28
29#ifdef __cplusplus
30extern "C" {
31#endif /* __cplusplus */
32
33/* defines ********************************************************************/
34
35/*
36 * LM80 register definition
37 *
38 * All registers are 8 bit wide
39 */
40#define LM80_CFG 0x00 /* Configuration Register */
41#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */
42#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */
43#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */
44#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */
45#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */
46#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */
47 /* 0x07 - 0x1f reserved */
48 /* current values */
49#define LM80_VT0_IN 0x20 /* current Voltage 0 value */
50#define LM80_VT1_IN 0x21 /* current Voltage 1 value */
51#define LM80_VT2_IN 0x22 /* current Voltage 2 value */
52#define LM80_VT3_IN 0x23 /* current Voltage 3 value */
53#define LM80_VT4_IN 0x24 /* current Voltage 4 value */
54#define LM80_VT5_IN 0x25 /* current Voltage 5 value */
55#define LM80_VT6_IN 0x26 /* current Voltage 6 value */
56#define LM80_TEMP_IN 0x27 /* current Temperature value */
57#define LM80_FAN1_IN 0x28 /* current Fan 1 count */
58#define LM80_FAN2_IN 0x29 /* current Fan 2 count */
59 /* limit values */
60#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */
61#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */
62#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */
63#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */
64#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */
65#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */
66#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */
67#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */
68#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */
69#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */
70#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */
71#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */
72#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */
73#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */
74#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */
75#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */
76#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */
77#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */
78#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */
79#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */
80 /* 0x3e - 0x3f reserved */
81
82/*
83 * LM80 bit definitions
84 */
85
86/* LM80_CFG Configuration Register */
87#define LM80_CFG_START (1<<0) /* start monitoring operation */
88#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */
89#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */
90#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */
91#define LM80_CFG_RESET (1<<4) /* signals a reset */
92#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */
93#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */
94#define LM80_CFG_INIT (1<<7) /* restore power on defaults */
95
96/* LM80_ISRC_1 Interrupt Status Register 1 */
97/* LM80_IMSK_1 Interrupt Mask Register 1 */
98#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */
99#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */
100#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */
101#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */
102#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */
103#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */
104#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */
105#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */
106
107/* LM80_ISRC_2 Interrupt Status Register 2 */
108/* LM80_IMSK_2 Interrupt Mask Register 2 */
109#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */
110#define LM80_IS_BTI (1<<1) /* state of BTI# pin */
111#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */
112#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */
113#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */
114#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */
115 /* bit 6 and 7 are reserved in LM80_ISRC_2 */
116#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */
117#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */
118
119/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */
120#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */
121#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */
122#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */
123#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */
124#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/
125#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */
126
127/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */
128#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */
129#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */
130#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */
131#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/
132#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */
133#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */
134
135 /* 0x07 - 0x1f reserved */
136/* LM80_VT0_IN current Voltage 0 value */
137/* LM80_VT1_IN current Voltage 1 value */
138/* LM80_VT2_IN current Voltage 2 value */
139/* LM80_VT3_IN current Voltage 3 value */
140/* LM80_VT4_IN current Voltage 4 value */
141/* LM80_VT5_IN current Voltage 5 value */
142/* LM80_VT6_IN current Voltage 6 value */
143/* LM80_TEMP_IN current temperature value */
144/* LM80_FAN1_IN current Fan 1 count */
145/* LM80_FAN2_IN current Fan 2 count */
146/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */
147/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */
148/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */
149/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */
150/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */
151/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */
152/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */
153/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */
154/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */
155/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */
156/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */
157/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */
158/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */
159/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */
160/* LM80_THOT_LIM_UP hot temperature limit (high) */
161/* LM80_THOT_LIM_LO hot temperature limit (low) */
162/* LM80_TOS_LIM_UP OS temperature limit (high) */
163/* LM80_TOS_LIM_LO OS temperature limit (low) */
164/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */
165/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */
166 /* 0x3e - 0x3f reserved */
167
168#define LM80_ADDR 0x28 /* LM80 default addr */
169
170/* typedefs *******************************************************************/
171
172
173/* function prototypes ********************************************************/
174
175#ifdef __cplusplus
176}
177#endif /* __cplusplus */
178
179#endif /* __INC_LM80_H */
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
deleted file mode 100644
index 423ad063d09b..000000000000
--- a/drivers/net/sk98lin/h/skaddr.h
+++ /dev/null
@@ -1,285 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skaddr.h
4 * Project: Gigabit Ethernet Adapters, ADDR-Modul
5 * Version: $Revision: 1.29 $
6 * Date: $Date: 2003/05/13 16:57:24 $
7 * Purpose: Header file for Address Management (MC, UC, Prom).
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage multicast addresses and promiscuous mode
30 * on GEnesis adapters.
31 *
32 * Include File Hierarchy:
33 *
34 * "skdrv1st.h"
35 * ...
36 * "sktypes.h"
37 * "skqueue.h"
38 * "skaddr.h"
39 * ...
40 * "skdrv2nd.h"
41 *
42 ******************************************************************************/
43
44#ifndef __INC_SKADDR_H
45#define __INC_SKADDR_H
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51/* defines ********************************************************************/
52
53#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
54#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
55
56/* ----- Common return values ----- */
57
58#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
59#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
60#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
61
62/* ----- Clear/Add flag bits ----- */
63
64#define SK_ADDR_PERMANENT 1 /* RLMT Address */
65
66/* ----- Additional Clear flag bits ----- */
67
68#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
69
70/* ----- Override flag bits ----- */
71
72#define SK_ADDR_LOGICAL_ADDRESS 0
73#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */
74#define SK_ADDR_PHYSICAL_ADDRESS 1
75#define SK_ADDR_CLEAR_LOGICAL 2
76#define SK_ADDR_SET_LOGICAL 4
77
78/* ----- Override return values ----- */
79
80#define SK_ADDR_OVERRIDE_SUCCESS (SK_ADDR_SUCCESS)
81#define SK_ADDR_DUPLICATE_ADDRESS 1
82#define SK_ADDR_MULTICAST_ADDRESS 2
83
84/* ----- Partitioning of excact match table ----- */
85
86#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
87
88#define SK_ADDR_FIRST_MATCH_RLMT 1
89#define SK_ADDR_LAST_MATCH_RLMT 2
90#define SK_ADDR_FIRST_MATCH_DRV 3
91#define SK_ADDR_LAST_MATCH_DRV (SK_ADDR_EXACT_MATCHES - 1)
92
93/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
94
95#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
96#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
97
98/* ----- Additional SkAddrMcAdd return values ----- */
99
100#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
101#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
102#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
103
104/* Promiscuous mode bits ----- */
105
106#define SK_PROM_MODE_NONE 0 /* Normal receive. */
107#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
108#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
109/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
110
111/* Macros */
112
113#ifdef OLD_STUFF
114#ifndef SK_ADDR_EQUAL
115/*
116 * "&" instead of "&&" allows better optimization on IA-64.
117 * The replacement is safe here, as all bytes exist.
118 */
119#ifndef SK_ADDR_DWORD_COMPARE
120#define SK_ADDR_EQUAL(A1,A2) ( \
121 (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
122 (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
123 (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
124 (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
125 (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
126 (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
127#else /* SK_ADDR_DWORD_COMPARE */
128#define SK_ADDR_EQUAL(A1,A2) ( \
129 (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
130 (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
131#endif /* SK_ADDR_DWORD_COMPARE */
132#endif /* SK_ADDR_EQUAL */
133#endif /* 0 */
134
135#ifndef SK_ADDR_EQUAL
136#ifndef SK_ADDR_DWORD_COMPARE
137#define SK_ADDR_EQUAL(A1,A2) ( \
138 (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \
139 (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \
140 (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \
141 (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \
142 (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \
143 (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0]))
144#else /* SK_ADDR_DWORD_COMPARE */
145#define SK_ADDR_EQUAL(A1,A2) ( \
146 (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \
147 *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \
148 (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \
149 *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0])))
150#endif /* SK_ADDR_DWORD_COMPARE */
151#endif /* SK_ADDR_EQUAL */
152
153/* typedefs *******************************************************************/
154
155typedef struct s_MacAddr {
156 SK_U8 a[SK_MAC_ADDR_LEN];
157} SK_MAC_ADDR;
158
159
160/* SK_FILTER is used to ensure alignment of the filter. */
161typedef union s_InexactFilter {
162 SK_U8 Bytes[8];
163 SK_U64 Val; /* Dummy entry for alignment only. */
164} SK_FILTER64;
165
166
167typedef struct s_AddrNet SK_ADDR_NET;
168
169
170typedef struct s_AddrPort {
171
172/* ----- Public part (read-only) ----- */
173
174 SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */
175 SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */
176 int PromMode; /* Promiscuous Mode. */
177
178/* ----- Private part ----- */
179
180 SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
181 SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
182 SK_U8 Align01;
183
184 SK_U32 FirstExactMatchRlmt;
185 SK_U32 NextExactMatchRlmt;
186 SK_U32 FirstExactMatchDrv;
187 SK_U32 NextExactMatchDrv;
188 SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES];
189 SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
190 SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */
191 SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */
192} SK_ADDR_PORT;
193
194
195struct s_AddrNet {
196/* ----- Public part (read-only) ----- */
197
198 SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
199 SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */
200
201/* ----- Private part ----- */
202
203 SK_U32 ActivePort; /* View of module ADDR. */
204 SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
205 SK_U8 Align01;
206 SK_U16 Align02;
207};
208
209
210typedef struct s_Addr {
211
212/* ----- Public part (read-only) ----- */
213
214 SK_ADDR_NET Net[SK_MAX_NETS];
215 SK_ADDR_PORT Port[SK_MAX_MACS];
216
217/* ----- Private part ----- */
218} SK_ADDR;
219
220/* function prototypes ********************************************************/
221
222#ifndef SK_KR_PROTO
223
224/* Functions provided by SkAddr */
225
226/* ANSI/C++ compliant function prototypes */
227
228extern int SkAddrInit(
229 SK_AC *pAC,
230 SK_IOC IoC,
231 int Level);
232
233extern int SkAddrMcClear(
234 SK_AC *pAC,
235 SK_IOC IoC,
236 SK_U32 PortNumber,
237 int Flags);
238
239extern int SkAddrMcAdd(
240 SK_AC *pAC,
241 SK_IOC IoC,
242 SK_U32 PortNumber,
243 SK_MAC_ADDR *pMc,
244 int Flags);
245
246extern int SkAddrMcUpdate(
247 SK_AC *pAC,
248 SK_IOC IoC,
249 SK_U32 PortNumber);
250
251extern int SkAddrOverride(
252 SK_AC *pAC,
253 SK_IOC IoC,
254 SK_U32 PortNumber,
255 SK_MAC_ADDR SK_FAR *pNewAddr,
256 int Flags);
257
258extern int SkAddrPromiscuousChange(
259 SK_AC *pAC,
260 SK_IOC IoC,
261 SK_U32 PortNumber,
262 int NewPromMode);
263
264#ifndef SK_SLIM
265extern int SkAddrSwap(
266 SK_AC *pAC,
267 SK_IOC IoC,
268 SK_U32 FromPortNumber,
269 SK_U32 ToPortNumber);
270#endif
271
272#else /* defined(SK_KR_PROTO)) */
273
274/* Non-ANSI/C++ compliant function prototypes */
275
276#error KR-style prototypes are not yet provided.
277
278#endif /* defined(SK_KR_PROTO)) */
279
280
281#ifdef __cplusplus
282}
283#endif /* __cplusplus */
284
285#endif /* __INC_SKADDR_H */
diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
deleted file mode 100644
index 6e256bd9a28c..000000000000
--- a/drivers/net/sk98lin/h/skcsum.h
+++ /dev/null
@@ -1,213 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skcsum.h
4 * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/08/20 13:59:57 $
7 * Purpose: Store/verify Internet checksum in send/receive packets.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2001 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/******************************************************************************
25 *
26 * Description:
27 *
28 * Public header file for the "GEnesis" common module "CSUM".
29 *
30 * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
31 * and is the code name of this SysKonnect project.
32 *
33 * Compilation Options:
34 *
35 * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
36 * empty module.
37 *
38 * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
39 * definitions. In this case, all SKCS_PROTO_xxx definitions must be made
40 * external.
41 *
42 * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
43 * definitions. In this case, all SKCS_STATUS_xxx definitions must be made
44 * external.
45 *
46 * Include File Hierarchy:
47 *
48 * "h/skcsum.h"
49 * "h/sktypes.h"
50 * "h/skqueue.h"
51 *
52 ******************************************************************************/
53
54#ifndef __INC_SKCSUM_H
55#define __INC_SKCSUM_H
56
57#include "h/sktypes.h"
58#include "h/skqueue.h"
59
60/* defines ********************************************************************/
61
62/*
63 * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags' if no user
64 * overwrite.
65 */
66#ifndef SKCS_OVERWRITE_PROTO /* User overwrite? */
67#define SKCS_PROTO_IP 0x1 /* IP (Internet Protocol version 4) */
68#define SKCS_PROTO_TCP 0x2 /* TCP (Transmission Control Protocol) */
69#define SKCS_PROTO_UDP 0x4 /* UDP (User Datagram Protocol) */
70
71/* Indices for protocol statistics. */
72#define SKCS_PROTO_STATS_IP 0
73#define SKCS_PROTO_STATS_UDP 1
74#define SKCS_PROTO_STATS_TCP 2
75#define SKCS_NUM_PROTOCOLS 3 /* Number of supported protocols. */
76#endif /* !SKCS_OVERWRITE_PROTO */
77
78/*
79 * Define the default SKCS_STATUS type and values if no user overwrite.
80 *
81 * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
82 * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
83 * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
84 * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
85 * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
86 * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
87 * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
88 * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
89 * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
90 * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
91 * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
92 */
93#ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */
94#define SKCS_STATUS int /* Define status type. */
95
96#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
97#define SKCS_STATUS_IP_CSUM_ERROR 2
98#define SKCS_STATUS_IP_FRAGMENT 3
99#define SKCS_STATUS_IP_CSUM_OK 4
100#define SKCS_STATUS_TCP_CSUM_ERROR 5
101#define SKCS_STATUS_UDP_CSUM_ERROR 6
102#define SKCS_STATUS_TCP_CSUM_OK 7
103#define SKCS_STATUS_UDP_CSUM_OK 8
104/* needed for Microsoft */
105#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9
106#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10
107/* UDP checksum may be omitted */
108#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11
109#endif /* !SKCS_OVERWRITE_STATUS */
110
111/* Clear protocol statistics event. */
112#define SK_CSUM_EVENT_CLEAR_PROTO_STATS 1
113
114/*
115 * Add two values in one's complement.
116 *
117 * Note: One of the two input values may be "longer" than 16-bit, but then the
118 * resulting sum may be 17 bits long. In this case, add zero to the result using
119 * SKCS_OC_ADD() again.
120 *
121 * Result = Value1 + Value2
122 */
123#define SKCS_OC_ADD(Result, Value1, Value2) { \
124 unsigned long Sum; \
125 \
126 Sum = (unsigned long) (Value1) + (unsigned long) (Value2); \
127 /* Add-in any carry. */ \
128 (Result) = (Sum & 0xffff) + (Sum >> 16); \
129}
130
131/*
132 * Subtract two values in one's complement.
133 *
134 * Result = Value1 - Value2
135 */
136#define SKCS_OC_SUB(Result, Value1, Value2) \
137 SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
138
139/* typedefs *******************************************************************/
140
141/*
142 * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
143 *
144 * There is one instance of this structure for each protocol supported.
145 */
146typedef struct s_CsProtocolStatistics {
147 SK_U64 RxOkCts; /* Receive checksum ok. */
148 SK_U64 RxUnableCts; /* Unable to verify receive checksum. */
149 SK_U64 RxErrCts; /* Receive checksum error. */
150 SK_U64 TxOkCts; /* Transmit checksum ok. */
151 SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */
152} SKCS_PROTO_STATS;
153
154/*
155 * s_Csum - The CSUM module context structure.
156 */
157typedef struct s_Csum {
158 /* Enabled receive SK_PROTO_XXX bit flags. */
159 unsigned ReceiveFlags[SK_MAX_NETS];
160#ifdef TX_CSUM
161 unsigned TransmitFlags[SK_MAX_NETS];
162#endif /* TX_CSUM */
163
164 /* The protocol statistics structure; one per supported protocol. */
165 SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
166} SK_CSUM;
167
168/*
169 * SKCS_PACKET_INFO - The packet information structure.
170 */
171typedef struct s_CsPacketInfo {
172 /* Bit field specifiying the desired/found protocols. */
173 unsigned ProtocolFlags;
174
175 /* Length of complete IP header, including any option fields. */
176 unsigned IpHeaderLength;
177
178 /* IP header checksum. */
179 unsigned IpHeaderChecksum;
180
181 /* TCP/UDP pseudo header checksum. */
182 unsigned PseudoHeaderChecksum;
183} SKCS_PACKET_INFO;
184
185/* function prototypes ********************************************************/
186
187#ifndef SK_CS_CALCULATE_CHECKSUM
188extern unsigned SkCsCalculateChecksum(
189 void *pData,
190 unsigned Length);
191#endif /* SK_CS_CALCULATE_CHECKSUM */
192
193extern int SkCsEvent(
194 SK_AC *pAc,
195 SK_IOC Ioc,
196 SK_U32 Event,
197 SK_EVPARA Param);
198
199extern SKCS_STATUS SkCsGetReceiveInfo(
200 SK_AC *pAc,
201 void *pIpHeader,
202 unsigned Checksum1,
203 unsigned Checksum2,
204 int NetNumber);
205
206extern void SkCsSetReceiveFlags(
207 SK_AC *pAc,
208 unsigned ReceiveFlags,
209 unsigned *pChecksum1Offset,
210 unsigned *pChecksum2Offset,
211 int NetNumber);
212
213#endif /* __INC_SKCSUM_H */
diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
deleted file mode 100644
index 3cba171d74b2..000000000000
--- a/drivers/net/sk98lin/h/skdebug.h
+++ /dev/null
@@ -1,74 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdebug.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.14 $
6 * Date: $Date: 2003/05/13 17:26:00 $
7 * Purpose: SK specific DEBUG support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKDEBUG_H
26#define __INC_SKDEBUG_H
27
28#ifdef DEBUG
29#ifndef SK_DBG_MSG
30#define SK_DBG_MSG(pAC,comp,cat,arg) \
31 if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \
32 ((cat) & SK_DBG_CHKCAT(pAC)) ) { \
33 SK_DBG_PRINTF arg ; \
34 }
35#endif
36#else
37#define SK_DBG_MSG(pAC,comp,lev,arg)
38#endif
39
40/* PLS NOTE:
41 * =========
42 * Due to any restrictions of kernel printf routines do not use other
43 * format identifiers as: %x %d %c %s .
44 * Never use any combined format identifiers such as: %lx %ld in your
45 * printf - argument (arg) because some OS specific kernel printfs may
46 * only support some basic identifiers.
47 */
48
49/* Debug modules */
50
51#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */
52#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
53#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
54#define SK_DBGMOD_VPD 0x00000008L /* VPD module */
55#define SK_DBGMOD_I2C 0x00000010L /* I2C module */
56#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
57#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
58#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
59#define SK_DBGMOD_PECP 0x00000100L /* PECP module */
60#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */
61
62/* Debug events */
63
64#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */
65#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */
66#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */
67#define SK_DBGCAT_TX 0x00000008L /* transmit path */
68#define SK_DBGCAT_RX 0x00000010L /* receive path */
69#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */
70#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */
71#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */
72#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */
73
74#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
deleted file mode 100644
index 91b8d4f45904..000000000000
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ /dev/null
@@ -1,188 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdrv1st.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.4 $
6 * Date: $Date: 2003/11/12 14:28:14 $
7 * Purpose: First header file for driver and all other modules
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the first include file of the driver, which includes all
30 * neccessary system header files and some of the GEnesis header files.
31 * It also defines some basic items.
32 *
33 * Include File Hierarchy:
34 *
35 * see skge.c
36 *
37 ******************************************************************************/
38
39#ifndef __INC_SKDRV1ST_H
40#define __INC_SKDRV1ST_H
41
42typedef struct s_AC SK_AC;
43
44/* Set card versions */
45#define SK_FAR
46
47/* override some default functions with optimized linux functions */
48
49#define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2)
50#define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4)
51#define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8)
52#define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2)
53#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4)
54#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8)
55
56#define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6))
57
58#include <linux/types.h>
59#include <linux/kernel.h>
60#include <linux/string.h>
61#include <linux/errno.h>
62#include <linux/ioport.h>
63#include <linux/slab.h>
64#include <linux/interrupt.h>
65#include <linux/pci.h>
66#include <linux/bitops.h>
67#include <asm/byteorder.h>
68#include <asm/io.h>
69#include <asm/irq.h>
70#include <linux/netdevice.h>
71#include <linux/etherdevice.h>
72#include <linux/skbuff.h>
73
74#include <linux/init.h>
75#include <asm/uaccess.h>
76#include <net/checksum.h>
77
78#define SK_CS_CALCULATE_CHECKSUM
79#ifndef CONFIG_X86_64
80#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff)
81#else
82#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff)
83#endif
84
85#include "h/sktypes.h"
86#include "h/skerror.h"
87#include "h/skdebug.h"
88#include "h/lm80.h"
89#include "h/xmac_ii.h"
90
91#ifdef __LITTLE_ENDIAN
92#define SK_LITTLE_ENDIAN
93#else
94#define SK_BIG_ENDIAN
95#endif
96
97#define SK_NET_DEVICE net_device
98
99
100/* we use gethrtime(), return unit: nanoseconds */
101#define SK_TICKS_PER_SEC 100
102
103#define SK_MEM_MAPPED_IO
104
105// #define SK_RLMT_SLOW_LOOKAHEAD
106
107#define SK_MAX_MACS 2
108#define SK_MAX_NETS 2
109
110#define SK_IOC char __iomem *
111
112typedef struct s_DrvRlmtMbuf SK_MBUF;
113
114#define SK_CONST64 INT64_C
115#define SK_CONSTU64 UINT64_C
116
117#define SK_MEMCPY(dest,src,size) memcpy(dest,src,size)
118#define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size)
119#define SK_MEMSET(dest,val,size) memset(dest,val,size)
120#define SK_STRLEN(pStr) strlen((char*)(pStr))
121#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size)
122#define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2))
123
124/* macros to access the adapter */
125#define SK_OUT8(b,a,v) writeb((v), ((b)+(a)))
126#define SK_OUT16(b,a,v) writew((v), ((b)+(a)))
127#define SK_OUT32(b,a,v) writel((v), ((b)+(a)))
128#define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a)))
129#define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a)))
130#define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a)))
131
132#define int8_t char
133#define int16_t short
134#define int32_t long
135#define int64_t long long
136#define uint8_t u_char
137#define uint16_t u_short
138#define uint32_t u_long
139#define uint64_t unsigned long long
140#define t_scalar_t int
141#define t_uscalar_t unsigned int
142#define uintptr_t unsigned long
143
144#define __CONCAT__(A,B) A##B
145
146#define INT32_C(a) __CONCAT__(a,L)
147#define INT64_C(a) __CONCAT__(a,LL)
148#define UINT32_C(a) __CONCAT__(a,UL)
149#define UINT64_C(a) __CONCAT__(a,ULL)
150
151#ifdef DEBUG
152#define SK_DBG_PRINTF printk
153#ifndef SK_DEBUG_CHKMOD
154#define SK_DEBUG_CHKMOD 0
155#endif
156#ifndef SK_DEBUG_CHKCAT
157#define SK_DEBUG_CHKCAT 0
158#endif
159/* those come from the makefile */
160#define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD)
161#define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT)
162
163extern void SkDbgPrintf(const char *format,...);
164
165#define SK_DBGMOD_DRV 0x00010000
166
167/**** possible driver debug categories ********************************/
168#define SK_DBGCAT_DRV_ENTRY 0x00010000
169#define SK_DBGCAT_DRV_SAP 0x00020000
170#define SK_DBGCAT_DRV_MCA 0x00040000
171#define SK_DBGCAT_DRV_TX_PROGRESS 0x00080000
172#define SK_DBGCAT_DRV_RX_PROGRESS 0x00100000
173#define SK_DBGCAT_DRV_PROGRESS 0x00200000
174#define SK_DBGCAT_DRV_MSG 0x00400000
175#define SK_DBGCAT_DRV_PROM 0x00800000
176#define SK_DBGCAT_DRV_TX_FRAME 0x01000000
177#define SK_DBGCAT_DRV_ERROR 0x02000000
178#define SK_DBGCAT_DRV_INT_SRC 0x04000000
179#define SK_DBGCAT_DRV_EVENT 0x08000000
180
181#endif
182
183#define SK_ERR_LOG SkErrorLog
184
185extern void SkErrorLog(SK_AC*, int, int, char*);
186
187#endif
188
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
deleted file mode 100644
index 3fa67171e832..000000000000
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ /dev/null
@@ -1,447 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdrv2nd.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/12/11 16:04:45 $
7 * Purpose: Second header file for driver and all other modules
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the second include file of the driver, which includes all other
30 * neccessary files and defines all structures and constants used by the
31 * driver and the common modules.
32 *
33 * Include File Hierarchy:
34 *
35 * see skge.c
36 *
37 ******************************************************************************/
38
39#ifndef __INC_SKDRV2ND_H
40#define __INC_SKDRV2ND_H
41
42#include "h/skqueue.h"
43#include "h/skgehwt.h"
44#include "h/sktimer.h"
45#include "h/ski2c.h"
46#include "h/skgepnmi.h"
47#include "h/skvpd.h"
48#include "h/skgehw.h"
49#include "h/skgeinit.h"
50#include "h/skaddr.h"
51#include "h/skgesirq.h"
52#include "h/skcsum.h"
53#include "h/skrlmt.h"
54#include "h/skgedrv.h"
55
56
57extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
58extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
59extern SK_U64 SkOsGetTime(SK_AC*);
60extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
61extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
62extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
63extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
64extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
65extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
66
67#ifdef SK_DIAG_SUPPORT
68extern int SkDrvEnterDiagMode(SK_AC *pAc);
69extern int SkDrvLeaveDiagMode(SK_AC *pAc);
70#endif
71
72struct s_DrvRlmtMbuf {
73 SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */
74 SK_U8 *pData; /* Data buffer (virtually contig.). */
75 unsigned Size; /* Data buffer size. */
76 unsigned Length; /* Length of packet (<= Size). */
77 SK_U32 PortIdx; /* Receiving/transmitting port. */
78#ifdef SK_RLMT_MBUF_PRIVATE
79 SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */
80#endif /* SK_RLMT_MBUF_PRIVATE */
81 struct sk_buff *pOs; /* Pointer to message block */
82};
83
84
85/*
86 * Time macros
87 */
88#if SK_TICKS_PER_SEC == 100
89#define SK_PNMI_HUNDREDS_SEC(t) (t)
90#else
91#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \
92 (SK_TICKS_PER_SEC))
93#endif
94
95/*
96 * New SkOsGetTime
97 */
98#define SkOsGetTimeCurrent(pAC, pUsec) {\
99 struct timeval t;\
100 do_gettimeofday(&t);\
101 *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
102}
103
104
105/*
106 * ioctl definitions
107 */
108#define SK_IOCTL_BASE (SIOCDEVPRIVATE)
109#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0)
110#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1)
111#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2)
112#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3)
113#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4)
114
115typedef struct s_IOCTL SK_GE_IOCTL;
116
117struct s_IOCTL {
118 char __user * pData;
119 unsigned int Len;
120};
121
122
123/*
124 * define sizes of descriptor rings in bytes
125 */
126
127#define TX_RING_SIZE (8*1024)
128#define RX_RING_SIZE (24*1024)
129
130/*
131 * Buffer size for ethernet packets
132 */
133#define ETH_BUF_SIZE 1540
134#define ETH_MAX_MTU 1514
135#define ETH_MIN_MTU 60
136#define ETH_MULTICAST_BIT 0x01
137#define SK_JUMBO_MTU 9000
138
139/*
140 * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
141 */
142#define TX_PRIO_LOW 0
143#define TX_PRIO_HIGH 1
144
145/*
146 * alignment of rx/tx descriptors
147 */
148#define DESCR_ALIGN 64
149
150/*
151 * definitions for pnmi. TODO
152 */
153#define SK_DRIVER_RESET(pAC, IoC) 0
154#define SK_DRIVER_SENDEVENT(pAC, IoC) 0
155#define SK_DRIVER_SELFTEST(pAC, IoC) 0
156/* For get mtu you must add an own function */
157#define SK_DRIVER_GET_MTU(pAc,IoC,i) 0
158#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
159#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0
160
161/*
162** Interim definition of SK_DRV_TIMER placed in this file until
163** common modules have been finalized
164*/
165#define SK_DRV_TIMER 11
166#define SK_DRV_MODERATION_TIMER 1
167#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */
168#define SK_DRV_RX_CLEANUP_TIMER 2
169#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */
170
171/*
172** Definitions regarding transmitting frames
173** any calculating any checksum.
174*/
175#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
176#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6
177#define C_LEN_ETHERMAC_HEADER_LENTYPE 2
178#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \
179 (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \
180 (C_LEN_ETHERMAC_HEADER_LENTYPE) )
181
182#define C_LEN_ETHERMTU_MINSIZE 46
183#define C_LEN_ETHERMTU_MAXSIZE_STD 1500
184#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000
185
186#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \
187 (C_LEN_ETHERMTU_MINSIZE) )
188
189#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER
190#define C_OFFSET_IPHEADER_IPPROTO 9
191#define C_OFFSET_TCPHEADER_TCPCS 16
192#define C_OFFSET_UDPHEADER_UDPCS 6
193
194#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \
195 (C_OFFSET_IPHEADER_IPPROTO) )
196
197#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */
198#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */
199
200/* TX and RX descriptors *****************************************************/
201
202typedef struct s_RxD RXD; /* the receive descriptor */
203
204struct s_RxD {
205 volatile SK_U32 RBControl; /* Receive Buffer Control */
206 SK_U32 VNextRxd; /* Next receive descriptor,low dword */
207 SK_U32 VDataLow; /* Receive buffer Addr, low dword */
208 SK_U32 VDataHigh; /* Receive buffer Addr, high dword */
209 SK_U32 FrameStat; /* Receive Frame Status word */
210 SK_U32 TimeStamp; /* Time stamp from XMAC */
211 SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */
212 SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */
213 RXD *pNextRxd; /* Pointer to next Rxd */
214 struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
215};
216
217typedef struct s_TxD TXD; /* the transmit descriptor */
218
219struct s_TxD {
220 volatile SK_U32 TBControl; /* Transmit Buffer Control */
221 SK_U32 VNextTxd; /* Next transmit descriptor,low dword */
222 SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */
223 SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */
224 SK_U32 FrameStat; /* Transmit Frame Status Word */
225 SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */
226 SK_U16 TcpSumSt; /* TCP Sum Start */
227 SK_U16 TcpSumWr; /* TCP Sum Write */
228 SK_U32 TcpReserved; /* not used */
229 TXD *pNextTxd; /* Pointer to next Txd */
230 struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
231};
232
233/* Used interrupt bits in the interrupts source register *********************/
234
235#define DRIVER_IRQS ((IS_IRQ_SW) | \
236 (IS_R1_F) |(IS_R2_F) | \
237 (IS_XS1_F) |(IS_XA1_F) | \
238 (IS_XS2_F) |(IS_XA2_F))
239
240#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \
241 (IS_EXT_REG) |(IS_TIMINT) | \
242 (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \
243 (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \
244 (IS_MAC1) |(IS_LNK_SYNC_M1)| \
245 (IS_MAC2) |(IS_LNK_SYNC_M2)| \
246 (IS_R1_C) |(IS_R2_C) | \
247 (IS_XS1_C) |(IS_XA1_C) | \
248 (IS_XS2_C) |(IS_XA2_C))
249
250#define IRQ_MASK ((IS_IRQ_SW) | \
251 (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \
252 (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \
253 (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \
254 (IS_HW_ERR) |(IS_I2C_READY)| \
255 (IS_EXT_REG) |(IS_TIMINT) | \
256 (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
257 (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
258 (IS_MAC1) |(IS_MAC2) | \
259 (IS_R1_C) |(IS_R2_C) | \
260 (IS_XS1_C) |(IS_XA1_C) | \
261 (IS_XS2_C) |(IS_XA2_C))
262
263#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */
264
265typedef struct s_DevNet DEV_NET;
266
267struct s_DevNet {
268 int PortNr;
269 int NetNr;
270 SK_AC *pAC;
271};
272
273typedef struct s_TxPort TX_PORT;
274
275struct s_TxPort {
276 /* the transmit descriptor rings */
277 caddr_t pTxDescrRing; /* descriptor area memory */
278 SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */
279 TXD *pTxdRingHead; /* Head of Tx rings */
280 TXD *pTxdRingTail; /* Tail of Tx rings */
281 TXD *pTxdRingPrev; /* descriptor sent previously */
282 int TxdRingFree; /* # of free entrys */
283 spinlock_t TxDesRingLock; /* serialize descriptor accesses */
284 SK_IOC HwAddr; /* bmu registers address */
285 int PortIndex; /* index number of port (0 or 1) */
286};
287
288typedef struct s_RxPort RX_PORT;
289
290struct s_RxPort {
291 /* the receive descriptor rings */
292 caddr_t pRxDescrRing; /* descriptor area memory */
293 SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */
294 RXD *pRxdRingHead; /* Head of Rx rings */
295 RXD *pRxdRingTail; /* Tail of Rx rings */
296 RXD *pRxdRingPrev; /* descriptor given to BMU previously */
297 int RxdRingFree; /* # of free entrys */
298 int RxCsum; /* use receive checksum hardware */
299 spinlock_t RxDesRingLock; /* serialize descriptor accesses */
300 int RxFillLimit; /* limit for buffers in ring */
301 SK_IOC HwAddr; /* bmu registers address */
302 int PortIndex; /* index number of port (0 or 1) */
303};
304
305/* Definitions needed for interrupt moderation *******************************/
306
307#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F))
308#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F))
309#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX))
310#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F))
311#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS)
312#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
313#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY))
314#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY))
315#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX))
316
317#define C_INT_MOD_NONE 1
318#define C_INT_MOD_STATIC 2
319#define C_INT_MOD_DYNAMIC 4
320
321#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */
322#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */
323
324#define C_INTS_PER_SEC_DEFAULT 2000
325#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */
326#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */
327#define C_INT_MOD_IPS_LOWER_RANGE 30
328#define C_INT_MOD_IPS_UPPER_RANGE 40000
329
330
331typedef struct s_DynIrqModInfo DIM_INFO;
332struct s_DynIrqModInfo {
333 unsigned long PrevTimeVal;
334 unsigned int PrevSysLoad;
335 unsigned int PrevUsedTime;
336 unsigned int PrevTotalTime;
337 int PrevUsedDescrRatio;
338 int NbrProcessedDescr;
339 SK_U64 PrevPort0RxIntrCts;
340 SK_U64 PrevPort1RxIntrCts;
341 SK_U64 PrevPort0TxIntrCts;
342 SK_U64 PrevPort1TxIntrCts;
343 SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */
344
345 int MaxModIntsPerSec; /* Moderation Threshold */
346 int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */
347 int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */
348
349 long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */
350 SK_BOOL DisplayStats; /* Stats yes/no */
351 SK_BOOL AutoSizing; /* Resize DIM-timer on/off */
352 int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */
353
354 SK_TIMER ModTimer; /* just some timer */
355};
356
357typedef struct s_PerStrm PER_STRM;
358
359#define SK_ALLOC_IRQ 0x00000001
360
361#ifdef SK_DIAG_SUPPORT
362#define DIAG_ACTIVE 1
363#define DIAG_NOTACTIVE 0
364#endif
365
366/****************************************************************************
367 * Per board structure / Adapter Context structure:
368 * Allocated within attach(9e) and freed within detach(9e).
369 * Contains all 'per device' necessary handles, flags, locks etc.:
370 */
371struct s_AC {
372 SK_GEINIT GIni; /* GE init struct */
373 SK_PNMI Pnmi; /* PNMI data struct */
374 SK_VPD vpd; /* vpd data struct */
375 SK_QUEUE Event; /* Event queue */
376 SK_HWT Hwt; /* Hardware Timer control struct */
377 SK_TIMCTRL Tim; /* Software Timer control struct */
378 SK_I2C I2c; /* I2C relevant data structure */
379 SK_ADDR Addr; /* for Address module */
380 SK_CSUM Csum; /* for checksum module */
381 SK_RLMT Rlmt; /* for rlmt module */
382 spinlock_t SlowPathLock; /* Normal IRQ lock */
383 struct timer_list BlinkTimer; /* for LED blinking */
384 int LedsOn;
385 SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
386 int RlmtMode; /* link check mode to set */
387 int RlmtNets; /* Number of nets */
388
389 SK_IOC IoBase; /* register set of adapter */
390 int BoardLevel; /* level of active hw init (0-2) */
391
392 SK_U32 AllocFlag; /* flag allocation of resources */
393 struct pci_dev *PciDev; /* for access to pci config space */
394 struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
395
396 int RxBufSize; /* length of receive buffers */
397 struct net_device_stats stats; /* linux 'netstat -i' statistics */
398 int Index; /* internal board index number */
399
400 /* adapter RAM sizes for queues of active port */
401 int RxQueueSize; /* memory used for receive queue */
402 int TxSQueueSize; /* memory used for sync. tx queue */
403 int TxAQueueSize; /* memory used for async. tx queue */
404
405 int PromiscCount; /* promiscuous mode counter */
406 int AllMultiCount; /* allmulticast mode counter */
407 int MulticCount; /* number of different MC */
408 /* addresses for this board */
409 /* (may be more than HW can)*/
410
411 int HWRevision; /* Hardware revision */
412 int ActivePort; /* the active XMAC port */
413 int MaxPorts; /* number of activated ports */
414 int TxDescrPerRing; /* # of descriptors per tx ring */
415 int RxDescrPerRing; /* # of descriptors per rx ring */
416
417 caddr_t pDescrMem; /* Pointer to the descriptor area */
418 dma_addr_t pDescrMemDMA; /* PCI DMA address of area */
419
420 /* the port structures with descriptor rings */
421 TX_PORT TxPort[SK_MAX_MACS][2];
422 RX_PORT RxPort[SK_MAX_MACS];
423
424 SK_BOOL CheckQueue; /* check event queue soon */
425 SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */
426 DIM_INFO DynIrqModInfo; /* all data related to DIM */
427
428 /* Only for tests */
429 int PortDown;
430 int ChipsetType; /* Chipset family type
431 * 0 == Genesis family support
432 * 1 == Yukon family support
433 */
434#ifdef SK_DIAG_SUPPORT
435 SK_U32 DiagModeActive; /* is diag active? */
436 SK_BOOL DiagFlowCtrl; /* for control purposes */
437 SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */
438 SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while
439 * DIAG is busy with NIC
440 */
441#endif
442
443};
444
445
446#endif /* __INC_SKDRV2ND_H */
447
diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
deleted file mode 100644
index da062f766238..000000000000
--- a/drivers/net/sk98lin/h/skerror.h
+++ /dev/null
@@ -1,55 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skerror.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2003/05/13 17:25:13 $
7 * Purpose: SK specific Error log support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _INC_SKERROR_H_
26#define _INC_SKERROR_H_
27
28/*
29 * Define Error Classes
30 */
31#define SK_ERRCL_OTHER (0) /* Other error */
32#define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */
33#define SK_ERRCL_INIT (1L<<1) /* Initialization error */
34#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */
35#define SK_ERRCL_SW (1L<<3) /* Internal Software error */
36#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */
37#define SK_ERRCL_COMM (1L<<5) /* Communication error */
38
39
40/*
41 * Define Error Code Bases
42 */
43#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */
44#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */
45#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */
46#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */
47#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */
48#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */
49#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */
50#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */
51#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */
52#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */
53#define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */
54
55#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
deleted file mode 100644
index 44fd4c3de818..000000000000
--- a/drivers/net/sk98lin/h/skgedrv.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgedrv.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/07/04 12:25:01 $
7 * Purpose: Interface with the driver
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEDRV_H_
26#define __INC_SKGEDRV_H_
27
28/* defines ********************************************************************/
29
30/*
31 * Define the driver events.
32 * Usually the events are defined by the destination module.
33 * In case of the driver we put the definition of the events here.
34 */
35#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */
36#define SK_DRV_NET_UP 2 /* The net is operational */
37#define SK_DRV_NET_DOWN 3 /* The net is down */
38#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */
39#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */
40#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */
41#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */
42#define SK_DRV_PORT_FAIL 8 /* One port fails */
43#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */
44#define SK_DRV_POWER_DOWN 10 /* Power down mode */
45#define SK_DRV_TIMER 11 /* Timer for free use */
46#ifdef SK_NO_RLMT
47#define SK_DRV_LINK_UP 12 /* Link Up event for driver */
48#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */
49#endif
50#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */
51#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
deleted file mode 100644
index f6282b7956db..000000000000
--- a/drivers/net/sk98lin/h/skgehw.h
+++ /dev/null
@@ -1,2126 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgehw.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.56 $
6 * Date: $Date: 2003/09/23 09:01:00 $
7 * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEHW_H
26#define __INC_SKGEHW_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34#define BIT_31 (1UL << 31)
35#define BIT_30 (1L << 30)
36#define BIT_29 (1L << 29)
37#define BIT_28 (1L << 28)
38#define BIT_27 (1L << 27)
39#define BIT_26 (1L << 26)
40#define BIT_25 (1L << 25)
41#define BIT_24 (1L << 24)
42#define BIT_23 (1L << 23)
43#define BIT_22 (1L << 22)
44#define BIT_21 (1L << 21)
45#define BIT_20 (1L << 20)
46#define BIT_19 (1L << 19)
47#define BIT_18 (1L << 18)
48#define BIT_17 (1L << 17)
49#define BIT_16 (1L << 16)
50#define BIT_15 (1L << 15)
51#define BIT_14 (1L << 14)
52#define BIT_13 (1L << 13)
53#define BIT_12 (1L << 12)
54#define BIT_11 (1L << 11)
55#define BIT_10 (1L << 10)
56#define BIT_9 (1L << 9)
57#define BIT_8 (1L << 8)
58#define BIT_7 (1L << 7)
59#define BIT_6 (1L << 6)
60#define BIT_5 (1L << 5)
61#define BIT_4 (1L << 4)
62#define BIT_3 (1L << 3)
63#define BIT_2 (1L << 2)
64#define BIT_1 (1L << 1)
65#define BIT_0 1L
66
67#define BIT_15S (1U << 15)
68#define BIT_14S (1 << 14)
69#define BIT_13S (1 << 13)
70#define BIT_12S (1 << 12)
71#define BIT_11S (1 << 11)
72#define BIT_10S (1 << 10)
73#define BIT_9S (1 << 9)
74#define BIT_8S (1 << 8)
75#define BIT_7S (1 << 7)
76#define BIT_6S (1 << 6)
77#define BIT_5S (1 << 5)
78#define BIT_4S (1 << 4)
79#define BIT_3S (1 << 3)
80#define BIT_2S (1 << 2)
81#define BIT_1S (1 << 1)
82#define BIT_0S 1
83
84#define SHIFT31(x) ((x) << 31)
85#define SHIFT30(x) ((x) << 30)
86#define SHIFT29(x) ((x) << 29)
87#define SHIFT28(x) ((x) << 28)
88#define SHIFT27(x) ((x) << 27)
89#define SHIFT26(x) ((x) << 26)
90#define SHIFT25(x) ((x) << 25)
91#define SHIFT24(x) ((x) << 24)
92#define SHIFT23(x) ((x) << 23)
93#define SHIFT22(x) ((x) << 22)
94#define SHIFT21(x) ((x) << 21)
95#define SHIFT20(x) ((x) << 20)
96#define SHIFT19(x) ((x) << 19)
97#define SHIFT18(x) ((x) << 18)
98#define SHIFT17(x) ((x) << 17)
99#define SHIFT16(x) ((x) << 16)
100#define SHIFT15(x) ((x) << 15)
101#define SHIFT14(x) ((x) << 14)
102#define SHIFT13(x) ((x) << 13)
103#define SHIFT12(x) ((x) << 12)
104#define SHIFT11(x) ((x) << 11)
105#define SHIFT10(x) ((x) << 10)
106#define SHIFT9(x) ((x) << 9)
107#define SHIFT8(x) ((x) << 8)
108#define SHIFT7(x) ((x) << 7)
109#define SHIFT6(x) ((x) << 6)
110#define SHIFT5(x) ((x) << 5)
111#define SHIFT4(x) ((x) << 4)
112#define SHIFT3(x) ((x) << 3)
113#define SHIFT2(x) ((x) << 2)
114#define SHIFT1(x) ((x) << 1)
115#define SHIFT0(x) ((x) << 0)
116
117/*
118 * Configuration Space header
119 * Since this module is used for different OS', those may be
120 * duplicate on some of them (e.g. Linux). But to keep the
121 * common source, we have to live with this...
122 */
123#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */
124#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */
125#define PCI_COMMAND 0x04 /* 16 bit Command */
126#define PCI_STATUS 0x06 /* 16 bit Status */
127#define PCI_REV_ID 0x08 /* 8 bit Revision ID */
128#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */
129#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */
130#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */
131#define PCI_HEADER_T 0x0e /* 8 bit Header Type */
132#define PCI_BIST 0x0f /* 8 bit Built-in selftest */
133#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */
134#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */
135 /* Byte 0x18..0x2b: reserved */
136#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */
137#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */
138#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */
139#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */
140 /* Byte 0x35..0x3b: reserved */
141#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */
142#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */
143#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */
144#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */
145 /* Device Dependent Region */
146#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */
147#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */
148 /* Power Management Region */
149#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */
150#define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */
151#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */
152#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */
153 /* Byte 0x4e: reserved */
154#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */
155 /* VPD Region */
156#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */
157#define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */
158#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */
159#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */
160 /* Byte 0x58..0x59: reserved */
161#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */
162 /* Byte 0x5c..0xff: reserved */
163
164/*
165 * I2C Address (PCI Config)
166 *
167 * Note: The temperature and voltage sensors are relocated on a different
168 * I2C bus.
169 */
170#define I2C_ADDR_VPD 0xa0 /* I2C address for the VPD EEPROM */
171
172/*
173 * Define Bits and Values of the registers
174 */
175/* PCI_COMMAND 16 bit Command */
176 /* Bit 15..11: reserved */
177#define PCI_INT_DIS BIT_10S /* Interrupt INTx# disable (PCI 2.3) */
178#define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */
179#define PCI_SERREN BIT_8S /* SERR enable */
180#define PCI_ADSTEP BIT_7S /* Address Stepping */
181#define PCI_PERREN BIT_6S /* Parity Report Response enable */
182#define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */
183#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */
184#define PCI_SCYCEN BIT_3S /* Special Cycle enable */
185#define PCI_BMEN BIT_2S /* Bus Master enable */
186#define PCI_MEMEN BIT_1S /* Memory Space Access enable */
187#define PCI_IOEN BIT_0S /* I/O Space Access enable */
188
189#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
190 PCI_BMEN | PCI_MEMEN | PCI_IOEN)
191
192/* PCI_STATUS 16 bit Status */
193#define PCI_PERR BIT_15S /* Parity Error */
194#define PCI_SERR BIT_14S /* Signaled SERR */
195#define PCI_RMABORT BIT_13S /* Received Master Abort */
196#define PCI_RTABORT BIT_12S /* Received Target Abort */
197 /* Bit 11: reserved */
198#define PCI_DEVSEL (3<<9) /* Bit 10.. 9: DEVSEL Timing */
199#define PCI_DEV_FAST (0<<9) /* fast */
200#define PCI_DEV_MEDIUM (1<<9) /* medium */
201#define PCI_DEV_SLOW (2<<9) /* slow */
202#define PCI_DATAPERR BIT_8S /* DATA Parity error detected */
203#define PCI_FB2BCAP BIT_7S /* Fast Back-to-Back Capability */
204#define PCI_UDF BIT_6S /* User Defined Features */
205#define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */
206#define PCI_NEWCAP BIT_4S /* New cap. list implemented */
207#define PCI_INT_STAT BIT_3S /* Interrupt INTx# Status (PCI 2.3) */
208 /* Bit 2.. 0: reserved */
209
210#define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
211 PCI_DATAPERR)
212
213/* PCI_CLASS_CODE 24 bit Class Code */
214/* Byte 2: Base Class (02) */
215/* Byte 1: SubClass (00) */
216/* Byte 0: Programming Interface (00) */
217
218/* PCI_CACHE_LSZ 8 bit Cache Line Size */
219/* Possible values: 0,2,4,8,16,32,64,128 */
220
221/* PCI_HEADER_T 8 bit Header Type */
222#define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */
223#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */
224
225/* PCI_BIST 8 bit Built-in selftest */
226/* Built-in Self test not supported (optional) */
227
228/* PCI_BASE_1ST 32 bit 1st Base address */
229#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */
230#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */
231#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */
232#define PCI_PREFEN BIT_3 /* Prefetchable */
233#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */
234#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */
235#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */
236#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */
237#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */
238
239/* PCI_BASE_2ND 32 bit 2nd Base address */
240#define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */
241#define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */
242 /* Bit 1: reserved */
243#define PCI_IOSPACE BIT_0 /* I/O Space Indicator */
244
245/* PCI_BASE_ROM 32 bit Expansion ROM Base Address */
246#define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */
247#define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */
248#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */
249 /* Bit 10.. 1: reserved */
250#define PCI_ROMEN BIT_0 /* Address Decode enable */
251
252/* Device Dependent Region */
253/* PCI_OUR_REG_1 32 bit Our Register 1 */
254 /* Bit 31..29: reserved */
255#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */
256#define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */
257#define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */
258#define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
259#define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */
260#define PCI_EN_IO BIT_23 /* Mapping to I/O space */
261#define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */
262 /* 1 = Map Flash to memory */
263 /* 0 = Disable addr. dec */
264#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */
265#define PCI_PAGE_16 (0L<<20) /* 16 k pages */
266#define PCI_PAGE_32K (1L<<20) /* 32 k pages */
267#define PCI_PAGE_64K (2L<<20) /* 64 k pages */
268#define PCI_PAGE_128K (3L<<20) /* 128 k pages */
269 /* Bit 19: reserved */
270#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */
271#define PCI_NOTAR BIT_15 /* No turnaround cycle */
272#define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */
273#define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */
274#define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */
275#define PCI_DIS_MWI BIT_11 /* Disable Mem Write & Invalidate */
276#define PCI_DISC_CLS BIT_10 /* Disc: cacheLsz bound */
277#define PCI_BURST_DIS BIT_9 /* Burst Disable */
278#define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */
279#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */
280#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */
281
282
283/* PCI_OUR_REG_2 32 bit Our Register 2 */
284#define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */
285#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */
286#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */
287 /* Bit 13..12: reserved */
288#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */
289#define PCI_PATCH_DIR_3 BIT_11
290#define PCI_PATCH_DIR_2 BIT_10
291#define PCI_PATCH_DIR_1 BIT_9
292#define PCI_PATCH_DIR_0 BIT_8
293#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7.. 4: Extended Patches 3..0 */
294#define PCI_EXT_PATCH_3 BIT_7
295#define PCI_EXT_PATCH_2 BIT_6
296#define PCI_EXT_PATCH_1 BIT_5
297#define PCI_EXT_PATCH_0 BIT_4
298#define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */
299#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */
300 /* Bit 1: reserved */
301#define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */
302
303
304/* Power Management Region */
305/* PCI_PM_CAP_REG 16 bit Power Management Capabilities */
306#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */
307#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */
308#define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */
309#define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */
310#define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */
311#define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */
312#define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */
313#define PCI_PM_D1_SUP BIT_9S /* D1 Support */
314 /* Bit 8.. 6: reserved */
315#define PCI_PM_DSI BIT_5S /* Device Specific Initialization */
316#define PCI_PM_APS BIT_4S /* Auxialiary Power Source */
317#define PCI_PME_CLOCK BIT_3S /* PM Event Clock */
318#define PCI_PM_VER_MSK 7 /* Bit 2.. 0: PM PCI Spec. version */
319
320/* PCI_PM_CTL_STS 16 bit Power Management Control/Status */
321#define PCI_PME_STATUS BIT_15S /* PME Status (YUKON only) */
322#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */
323#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */
324#define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */
325 /* Bit 7.. 2: reserved */
326#define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */
327
328#define PCI_PM_STATE_D0 0 /* D0: Operational (default) */
329#define PCI_PM_STATE_D1 1 /* D1: (YUKON only) */
330#define PCI_PM_STATE_D2 2 /* D2: (YUKON only) */
331#define PCI_PM_STATE_D3 3 /* D3: HOT, Power Down and Reset */
332
333/* VPD Region */
334/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
335#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */
336#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */
337
338/* Control Register File (Address Map) */
339
340/*
341 * Bank 0
342 */
343#define B0_RAP 0x0000 /* 8 bit Register Address Port */
344 /* 0x0001 - 0x0003: reserved */
345#define B0_CTST 0x0004 /* 16 bit Control/Status register */
346#define B0_LED 0x0006 /* 8 Bit LED register */
347#define B0_POWER_CTRL 0x0007 /* 8 Bit Power Control reg (YUKON only) */
348#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */
349#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */
350#define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */
351#define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */
352#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */
353 /* 0x001c: reserved */
354
355/* B0 XMAC 1 registers (GENESIS only) */
356#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/
357 /* 0x0022 - 0x0027: reserved */
358#define B0_XM1_ISRC 0x0028 /* 16 bit ro XMAC 1 Interrupt Status Reg */
359 /* 0x002a - 0x002f: reserved */
360#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w XMAC 1 PHY Address Register */
361 /* 0x0032 - 0x0033: reserved */
362#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w XMAC 1 PHY Data Register */
363 /* 0x0036 - 0x003f: reserved */
364
365/* B0 XMAC 2 registers (GENESIS only) */
366#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/
367 /* 0x0042 - 0x0047: reserved */
368#define B0_XM2_ISRC 0x0048 /* 16 bit ro XMAC 2 Interrupt Status Reg */
369 /* 0x004a - 0x004f: reserved */
370#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w XMAC 2 PHY Address Register */
371 /* 0x0052 - 0x0053: reserved */
372#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */
373 /* 0x0056 - 0x005f: reserved */
374
375/* BMU Control Status Registers */
376#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */
377#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */
378#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
379#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/
380#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
381#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/
382 /* 0x0078 - 0x007f: reserved */
383
384/*
385 * Bank 1
386 * - completely empty (this is the RAP Block window)
387 * Note: if RAP = 1 this page is reserved
388 */
389
390/*
391 * Bank 2
392 */
393/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
394#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */
395 /* 0x0106 - 0x0107: reserved */
396#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */
397 /* 0x010e - 0x010f: reserved */
398#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */
399 /* 0x0116 - 0x0117: reserved */
400#define B2_CONN_TYP 0x0118 /* 8 bit Connector type */
401#define B2_PMD_TYP 0x0119 /* 8 bit PMD type */
402#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */
403#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */
404 /* Eprom registers are currently of no use */
405#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */
406#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */
407#define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */
408#define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */
409#define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */
410#define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */
411 /* 0x0125 - 0x0127: reserved */
412#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */
413#define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */
414 /* 0x012a - 0x012f: reserved */
415#define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */
416#define B2_TI_VAL 0x0134 /* 32 bit Timer Value */
417#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */
418#define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */
419 /* 0x013a - 0x013f: reserved */
420#define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/
421#define B2_IRQM_VAL 0x0144 /* 32 bit IRQ Moderation Timer Value */
422#define B2_IRQM_CTRL 0x0148 /* 8 bit IRQ Moderation Timer Control */
423#define B2_IRQM_TEST 0x0149 /* 8 bit IRQ Moderation Timer Test */
424#define B2_IRQM_MSK 0x014c /* 32 bit IRQ Moderation Mask */
425#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit IRQ Moderation HW Error Mask */
426 /* 0x0154 - 0x0157: reserved */
427#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */
428#define B2_TST_CTRL2 0x0159 /* 8 bit Test Control Register 2 */
429 /* 0x015a - 0x015b: reserved */
430#define B2_GP_IO 0x015c /* 32 bit General Purpose I/O Register */
431#define B2_I2C_CTRL 0x0160 /* 32 bit I2C HW Control Register */
432#define B2_I2C_DATA 0x0164 /* 32 bit I2C HW Data Register */
433#define B2_I2C_IRQ 0x0168 /* 32 bit I2C HW IRQ Register */
434#define B2_I2C_SW 0x016c /* 32 bit I2C SW Port Register */
435
436/* Blink Source Counter (GENESIS only) */
437#define B2_BSC_INI 0x0170 /* 32 bit Blink Source Counter Init Val */
438#define B2_BSC_VAL 0x0174 /* 32 bit Blink Source Counter Value */
439#define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */
440#define B2_BSC_STAT 0x0179 /* 8 bit Blink Source Counter Status */
441#define B2_BSC_TST 0x017a /* 16 bit Blink Source Counter Test Reg */
442 /* 0x017c - 0x017f: reserved */
443
444/*
445 * Bank 3
446 */
447/* RAM Random Registers */
448#define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */
449#define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */
450#define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */
451 /* 0x018c - 0x018f: reserved */
452
453/* RAM Interface Registers */
454/*
455 * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
456 * not usable in SW. Please notice these are NOT real timeouts, these are
457 * the number of qWords transferred continuously.
458 */
459#define B3_RI_WTO_R1 0x0190 /* 8 bit WR Timeout Queue R1 (TO0) */
460#define B3_RI_WTO_XA1 0x0191 /* 8 bit WR Timeout Queue XA1 (TO1) */
461#define B3_RI_WTO_XS1 0x0192 /* 8 bit WR Timeout Queue XS1 (TO2) */
462#define B3_RI_RTO_R1 0x0193 /* 8 bit RD Timeout Queue R1 (TO3) */
463#define B3_RI_RTO_XA1 0x0194 /* 8 bit RD Timeout Queue XA1 (TO4) */
464#define B3_RI_RTO_XS1 0x0195 /* 8 bit RD Timeout Queue XS1 (TO5) */
465#define B3_RI_WTO_R2 0x0196 /* 8 bit WR Timeout Queue R2 (TO6) */
466#define B3_RI_WTO_XA2 0x0197 /* 8 bit WR Timeout Queue XA2 (TO7) */
467#define B3_RI_WTO_XS2 0x0198 /* 8 bit WR Timeout Queue XS2 (TO8) */
468#define B3_RI_RTO_R2 0x0199 /* 8 bit RD Timeout Queue R2 (TO9) */
469#define B3_RI_RTO_XA2 0x019a /* 8 bit RD Timeout Queue XA2 (TO10)*/
470#define B3_RI_RTO_XS2 0x019b /* 8 bit RD Timeout Queue XS2 (TO11)*/
471#define B3_RI_TO_VAL 0x019c /* 8 bit Current Timeout Count Val */
472 /* 0x019d - 0x019f: reserved */
473#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Interface Control Register */
474#define B3_RI_TEST 0x01a2 /* 8 bit RAM Interface Test Register */
475 /* 0x01a3 - 0x01af: reserved */
476
477/* MAC Arbiter Registers (GENESIS only) */
478/* these are the no. of qWord transferred continuously and NOT real timeouts */
479#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Val Rx Path MAC 1 */
480#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Val Rx Path MAC 2 */
481#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Val Tx Path MAC 1 */
482#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Val Tx Path MAC 2 */
483#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */
484#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */
485#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */
486#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */
487#define B3_MA_TO_CTRL 0x01b8 /* 16 bit MAC Arbiter Timeout Ctrl Reg */
488#define B3_MA_TO_TEST 0x01ba /* 16 bit MAC Arbiter Timeout Test Reg */
489 /* 0x01bc - 0x01bf: reserved */
490#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Val Rx Path MAC 1 */
491#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Val Rx Path MAC 2 */
492#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Val Tx Path MAC 1 */
493#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Val Tx Path MAC 2 */
494#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */
495#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */
496#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */
497#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */
498#define B3_MA_RC_CTRL 0x01c8 /* 16 bit MAC Arbiter Recovery Ctrl Reg */
499#define B3_MA_RC_TEST 0x01ca /* 16 bit MAC Arbiter Recovery Test Reg */
500 /* 0x01cc - 0x01cf: reserved */
501
502/* Packet Arbiter Registers (GENESIS only) */
503/* these are real timeouts */
504#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1 */
505 /* 0x01d2 - 0x01d3: reserved */
506#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2 */
507 /* 0x01d6 - 0x01d7: reserved */
508#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1 */
509 /* 0x01da - 0x01db: reserved */
510#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2 */
511 /* 0x01de - 0x01df: reserved */
512#define B3_PA_TOVAL_RX1 0x01e0 /* 16 bit Timeout Val Rx Path MAC 1 */
513 /* 0x01e2 - 0x01e3: reserved */
514#define B3_PA_TOVAL_RX2 0x01e4 /* 16 bit Timeout Val Rx Path MAC 2 */
515 /* 0x01e6 - 0x01e7: reserved */
516#define B3_PA_TOVAL_TX1 0x01e8 /* 16 bit Timeout Val Tx Path MAC 1 */
517 /* 0x01ea - 0x01eb: reserved */
518#define B3_PA_TOVAL_TX2 0x01ec /* 16 bit Timeout Val Tx Path MAC 2 */
519 /* 0x01ee - 0x01ef: reserved */
520#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */
521#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */
522 /* 0x01f4 - 0x01ff: reserved */
523
524/*
525 * Bank 4 - 5
526 */
527/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
528#define TXA_ITI_INI 0x0200 /* 32 bit Tx Arb Interval Timer Init Val*/
529#define TXA_ITI_VAL 0x0204 /* 32 bit Tx Arb Interval Timer Value */
530#define TXA_LIM_INI 0x0208 /* 32 bit Tx Arb Limit Counter Init Val */
531#define TXA_LIM_VAL 0x020c /* 32 bit Tx Arb Limit Counter Value */
532#define TXA_CTRL 0x0210 /* 8 bit Tx Arbiter Control Register */
533#define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */
534#define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */
535 /* 0x0213 - 0x027f: reserved */
536 /* 0x0280 - 0x0292: MAC 2 */
537 /* 0x0213 - 0x027f: reserved */
538
539/*
540 * Bank 6
541 */
542/* External registers (GENESIS only) */
543#define B6_EXT_REG 0x0300
544
545/*
546 * Bank 7
547 */
548/* This is a copy of the Configuration register file (lower half) */
549#define B7_CFG_SPC 0x0380
550
551/*
552 * Bank 8 - 15
553 */
554/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
555#define B8_Q_REGS 0x0400
556
557/* Queue Register Offsets, use Q_ADDR() to access */
558#define Q_D 0x00 /* 8*32 bit Current Descriptor */
559#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low dWord */
560#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High dWord */
561#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low dWord */
562#define Q_AC_H 0x2c /* 32 bit Current Address Counter High dWord */
563#define Q_BC 0x30 /* 32 bit Current Byte Counter */
564#define Q_CSR 0x34 /* 32 bit BMU Control/Status Register */
565#define Q_F 0x38 /* 32 bit Flag Register */
566#define Q_T1 0x3c /* 32 bit Test Register 1 */
567#define Q_T1_TR 0x3c /* 8 bit Test Register 1 Transfer SM */
568#define Q_T1_WR 0x3d /* 8 bit Test Register 1 Write Descriptor SM */
569#define Q_T1_RD 0x3e /* 8 bit Test Register 1 Read Descriptor SM */
570#define Q_T1_SV 0x3f /* 8 bit Test Register 1 Supervisor SM */
571#define Q_T2 0x40 /* 32 bit Test Register 2 */
572#define Q_T3 0x44 /* 32 bit Test Register 3 */
573 /* 0x48 - 0x7f: reserved */
574
575/*
576 * Bank 16 - 23
577 */
578/* RAM Buffer Registers */
579#define B16_RAM_REGS 0x0800
580
581/* RAM Buffer Register Offsets, use RB_ADDR() to access */
582#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */
583#define RB_END 0x04 /* 32 bit RAM Buffer End Address */
584#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */
585#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */
586#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */
587#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */
588#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */
589#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */
590 /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
591#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */
592#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */
593#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */
594#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */
595#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */
596 /* 0x2c - 0x7f: reserved */
597
598/*
599 * Bank 24
600 */
601/*
602 * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
603 * use MR_ADDR() to access
604 */
605#define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */
606#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */
607 /* 0x0c08 - 0x0c0b: reserved */
608#define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */
609#define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */
610#define RX_MFF_LEV 0x0c14 /* 32 bit Receive MAC FIFO Level */
611#define RX_MFF_CTRL1 0x0c18 /* 16 bit Receive MAC FIFO Control Reg 1*/
612#define RX_MFF_STAT_TO 0x0c1a /* 8 bit Receive MAC Status Timeout */
613#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Time Stamp Timeout */
614#define RX_MFF_CTRL2 0x0c1c /* 8 bit Receive MAC FIFO Control Reg 2*/
615#define RX_MFF_TST1 0x0c1d /* 8 bit Receive MAC FIFO Test Reg 1 */
616#define RX_MFF_TST2 0x0c1e /* 8 bit Receive MAC FIFO Test Reg 2 */
617 /* 0x0c1f: reserved */
618#define RX_LED_INI 0x0c20 /* 32 bit Receive LED Cnt Init Value */
619#define RX_LED_VAL 0x0c24 /* 32 bit Receive LED Cnt Current Value */
620#define RX_LED_CTRL 0x0c28 /* 8 bit Receive LED Cnt Control Reg */
621#define RX_LED_TST 0x0c29 /* 8 bit Receive LED Cnt Test Register */
622 /* 0x0c2a - 0x0c2f: reserved */
623#define LNK_SYNC_INI 0x0c30 /* 32 bit Link Sync Cnt Init Value */
624#define LNK_SYNC_VAL 0x0c34 /* 32 bit Link Sync Cnt Current Value */
625#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register */
626#define LNK_SYNC_TST 0x0c39 /* 8 bit Link Sync Cnt Test Register */
627 /* 0x0c3a - 0x0c3b: reserved */
628#define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */
629 /* 0x0c3d - 0x0c3f: reserved */
630
631/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
632#define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */
633#define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */
634#define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */
635#define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */
636#define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */
637 /* 0x0c54 - 0x0c5f: reserved */
638#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */
639 /* 0x0c64 - 0x0c67: reserved */
640#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */
641 /* 0x0c6c - 0x0c6f: reserved */
642#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */
643 /* 0x0c74 - 0x0c77: reserved */
644#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */
645 /* 0x0c7c - 0x0c7f: reserved */
646
647/*
648 * Bank 25
649 */
650 /* 0x0c80 - 0x0cbf: MAC 2 */
651 /* 0x0cc0 - 0x0cff: reserved */
652
653/*
654 * Bank 26
655 */
656/*
657 * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
658 * use MR_ADDR() to access
659 */
660#define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */
661#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */
662#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */
663#define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */
664#define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */
665#define TX_MFF_LEV 0x0d14 /* 32 bit Transmit MAC FIFO Level */
666#define TX_MFF_CTRL1 0x0d18 /* 16 bit Transmit MAC FIFO Ctrl Reg 1 */
667#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush */
668 /* 0x0c1b: reserved */
669#define TX_MFF_CTRL2 0x0d1c /* 8 bit Transmit MAC FIFO Ctrl Reg 2 */
670#define TX_MFF_TST1 0x0d1d /* 8 bit Transmit MAC FIFO Test Reg 1 */
671#define TX_MFF_TST2 0x0d1e /* 8 bit Transmit MAC FIFO Test Reg 2 */
672 /* 0x0d1f: reserved */
673#define TX_LED_INI 0x0d20 /* 32 bit Transmit LED Cnt Init Value */
674#define TX_LED_VAL 0x0d24 /* 32 bit Transmit LED Cnt Current Val */
675#define TX_LED_CTRL 0x0d28 /* 8 bit Transmit LED Cnt Control Reg */
676#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */
677 /* 0x0d2a - 0x0d3f: reserved */
678
679/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
680#define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */
681#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
682#define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */
683 /* 0x0d4c - 0x0d5f: reserved */
684#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */
685#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */
686#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */
687 /* 0x0d6c - 0x0d6f: reserved */
688#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */
689#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */
690#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */
691 /* 0x0d7c - 0x0d7f: reserved */
692
693/*
694 * Bank 27
695 */
696 /* 0x0d80 - 0x0dbf: MAC 2 */
697 /* 0x0daa - 0x0dff: reserved */
698
699/*
700 * Bank 28
701 */
702/* Descriptor Poll Timer Registers */
703#define B28_DPT_INI 0x0e00 /* 24 bit Descriptor Poll Timer Init Val */
704#define B28_DPT_VAL 0x0e04 /* 24 bit Descriptor Poll Timer Curr Val */
705#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg */
706 /* 0x0e09: reserved */
707#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg */
708 /* 0x0e0b: reserved */
709
710/* Time Stamp Timer Registers (YUKON only) */
711 /* 0x0e10: reserved */
712#define GMAC_TI_ST_VAL 0x0e14 /* 32 bit Time Stamp Timer Curr Val */
713#define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */
714 /* 0x0e19: reserved */
715#define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */
716 /* 0x0e1b - 0x0e7f: reserved */
717
718/*
719 * Bank 29
720 */
721 /* 0x0e80 - 0x0efc: reserved */
722
723/*
724 * Bank 30
725 */
726/* GMAC and GPHY Control Registers (YUKON only) */
727#define GMAC_CTRL 0x0f00 /* 32 bit GMAC Control Reg */
728#define GPHY_CTRL 0x0f04 /* 32 bit GPHY Control Reg */
729#define GMAC_IRQ_SRC 0x0f08 /* 8 bit GMAC Interrupt Source Reg */
730 /* 0x0f09 - 0x0f0b: reserved */
731#define GMAC_IRQ_MSK 0x0f0c /* 8 bit GMAC Interrupt Mask Reg */
732 /* 0x0f0d - 0x0f0f: reserved */
733#define GMAC_LINK_CTRL 0x0f10 /* 16 bit Link Control Reg */
734 /* 0x0f14 - 0x0f1f: reserved */
735
736/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
737
738#define WOL_REG_OFFS 0x20 /* HW-Bug: Address is + 0x20 against spec. */
739
740#define WOL_CTRL_STAT 0x0f20 /* 16 bit WOL Control/Status Reg */
741#define WOL_MATCH_CTL 0x0f22 /* 8 bit WOL Match Control Reg */
742#define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */
743#define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */
744#define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */
745#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */
746
747/* use this macro to access above registers */
748#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs))
749
750
751/* WOL Pattern Length Registers (YUKON only) */
752
753#define WOL_PATT_LEN_LO 0x0f30 /* 32 bit WOL Pattern Length 3..0 */
754#define WOL_PATT_LEN_HI 0x0f34 /* 24 bit WOL Pattern Length 6..4 */
755
756/* WOL Pattern Counter Registers (YUKON only) */
757
758#define WOL_PATT_CNT_0 0x0f38 /* 32 bit WOL Pattern Counter 3..0 */
759#define WOL_PATT_CNT_4 0x0f3c /* 24 bit WOL Pattern Counter 6..4 */
760 /* 0x0f40 - 0x0f7f: reserved */
761
762/*
763 * Bank 31
764 */
765/* 0x0f80 - 0x0fff: reserved */
766
767/*
768 * Bank 32 - 33
769 */
770#define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */
771
772/*
773 * Bank 0x22 - 0x3f
774 */
775/* 0x1100 - 0x1fff: reserved */
776
777/*
778 * Bank 0x40 - 0x4f
779 */
780#define BASE_XMAC_1 0x2000 /* XMAC 1 registers */
781
782/*
783 * Bank 0x50 - 0x5f
784 */
785
786#define BASE_GMAC_1 0x2800 /* GMAC 1 registers */
787
788/*
789 * Bank 0x60 - 0x6f
790 */
791#define BASE_XMAC_2 0x3000 /* XMAC 2 registers */
792
793/*
794 * Bank 0x70 - 0x7f
795 */
796#define BASE_GMAC_2 0x3800 /* GMAC 2 registers */
797
798/*
799 * Control Register Bit Definitions:
800 */
801/* B0_RAP 8 bit Register Address Port */
802 /* Bit 7: reserved */
803#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */
804
805/* B0_CTST 16 bit Control/Status register */
806 /* Bit 15..14: reserved */
807#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */
808#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */
809#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */
810#define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */
811#define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */
812#define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */
813#define CS_ST_SW_IRQ BIT_7S /* Set IRQ SW Request */
814#define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */
815#define CS_STOP_DONE BIT_5S /* Stop Master is finished */
816#define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */
817#define CS_MRST_CLR BIT_3S /* Clear Master reset */
818#define CS_MRST_SET BIT_2S /* Set Master reset */
819#define CS_RST_CLR BIT_1S /* Clear Software reset */
820#define CS_RST_SET BIT_0S /* Set Software reset */
821
822/* B0_LED 8 Bit LED register */
823 /* Bit 7.. 2: reserved */
824#define LED_STAT_ON BIT_1S /* Status LED on */
825#define LED_STAT_OFF BIT_0S /* Status LED off */
826
827/* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */
828#define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */
829#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */
830#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */
831#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */
832#define PC_VAUX_ON BIT_3 /* Switch VAUX On */
833#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */
834#define PC_VCC_ON BIT_1 /* Switch VCC On */
835#define PC_VCC_OFF BIT_0 /* Switch VCC Off */
836
837/* B0_ISRC 32 bit Interrupt Source Register */
838/* B0_IMSK 32 bit Interrupt Mask Register */
839/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */
840/* B2_IRQM_MSK 32 bit IRQ Moderation Mask */
841#define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */
842#define IS_HW_ERR BIT_31 /* Interrupt HW Error */
843 /* Bit 30: reserved */
844#define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */
845#define IS_PA_TO_RX2 BIT_28 /* Packet Arb Timeout Rx2 */
846#define IS_PA_TO_TX1 BIT_27 /* Packet Arb Timeout Tx1 */
847#define IS_PA_TO_TX2 BIT_26 /* Packet Arb Timeout Tx2 */
848#define IS_I2C_READY BIT_25 /* IRQ on end of I2C Tx */
849#define IS_IRQ_SW BIT_24 /* SW forced IRQ */
850#define IS_EXT_REG BIT_23 /* IRQ from LM80 or PHY (GENESIS only) */
851 /* IRQ from PHY (YUKON only) */
852#define IS_TIMINT BIT_22 /* IRQ from Timer */
853#define IS_MAC1 BIT_21 /* IRQ from MAC 1 */
854#define IS_LNK_SYNC_M1 BIT_20 /* Link Sync Cnt wrap MAC 1 */
855#define IS_MAC2 BIT_19 /* IRQ from MAC 2 */
856#define IS_LNK_SYNC_M2 BIT_18 /* Link Sync Cnt wrap MAC 2 */
857/* Receive Queue 1 */
858#define IS_R1_B BIT_17 /* Q_R1 End of Buffer */
859#define IS_R1_F BIT_16 /* Q_R1 End of Frame */
860#define IS_R1_C BIT_15 /* Q_R1 Encoding Error */
861/* Receive Queue 2 */
862#define IS_R2_B BIT_14 /* Q_R2 End of Buffer */
863#define IS_R2_F BIT_13 /* Q_R2 End of Frame */
864#define IS_R2_C BIT_12 /* Q_R2 Encoding Error */
865/* Synchronous Transmit Queue 1 */
866#define IS_XS1_B BIT_11 /* Q_XS1 End of Buffer */
867#define IS_XS1_F BIT_10 /* Q_XS1 End of Frame */
868#define IS_XS1_C BIT_9 /* Q_XS1 Encoding Error */
869/* Asynchronous Transmit Queue 1 */
870#define IS_XA1_B BIT_8 /* Q_XA1 End of Buffer */
871#define IS_XA1_F BIT_7 /* Q_XA1 End of Frame */
872#define IS_XA1_C BIT_6 /* Q_XA1 Encoding Error */
873/* Synchronous Transmit Queue 2 */
874#define IS_XS2_B BIT_5 /* Q_XS2 End of Buffer */
875#define IS_XS2_F BIT_4 /* Q_XS2 End of Frame */
876#define IS_XS2_C BIT_3 /* Q_XS2 Encoding Error */
877/* Asynchronous Transmit Queue 2 */
878#define IS_XA2_B BIT_2 /* Q_XA2 End of Buffer */
879#define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */
880#define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */
881
882
883/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */
884/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */
885/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
886#define IS_ERR_MSK 0x00000fffL /* All Error bits */
887 /* Bit 31..14: reserved */
888#define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */
889#define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */
890#define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */
891#define IS_IRQ_STAT BIT_10 /* IRQ status exception */
892#define IS_NO_STAT_M1 BIT_9 /* No Rx Status from MAC 1 */
893#define IS_NO_STAT_M2 BIT_8 /* No Rx Status from MAC 2 */
894#define IS_NO_TIST_M1 BIT_7 /* No Time Stamp from MAC 1 */
895#define IS_NO_TIST_M2 BIT_6 /* No Time Stamp from MAC 2 */
896#define IS_RAM_RD_PAR BIT_5 /* RAM Read Parity Error */
897#define IS_RAM_WR_PAR BIT_4 /* RAM Write Parity Error */
898#define IS_M1_PAR_ERR BIT_3 /* MAC 1 Parity Error */
899#define IS_M2_PAR_ERR BIT_2 /* MAC 2 Parity Error */
900#define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */
901#define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */
902
903/* B2_CONN_TYP 8 bit Connector type */
904/* B2_PMD_TYP 8 bit PMD type */
905/* Values of connector and PMD type comply to SysKonnect internal std */
906
907/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */
908#define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */
909 /* Bit 3.. 2: reserved */
910#define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */
911#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/
912
913/* B2_CHIP_ID 8 bit Chip Identification Number */
914#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */
915#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */
916#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */
917#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */
918
919#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */
920#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */
921
922/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */
923#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */
924
925/* B2_LD_CTRL 8 bit EPROM loader control register */
926/* Bits are currently reserved */
927
928/* B2_LD_TEST 8 bit EPROM loader test register */
929 /* Bit 7.. 4: reserved */
930#define LD_T_ON BIT_3S /* Loader Test mode on */
931#define LD_T_OFF BIT_2S /* Loader Test mode off */
932#define LD_T_STEP BIT_1S /* Decrement FPROM addr. Counter */
933#define LD_START BIT_0S /* Start loading FPROM */
934
935/*
936 * Timer Section
937 */
938/* B2_TI_CTRL 8 bit Timer control */
939/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
940 /* Bit 7.. 3: reserved */
941#define TIM_START BIT_2S /* Start Timer */
942#define TIM_STOP BIT_1S /* Stop Timer */
943#define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */
944
945/* B2_TI_TEST 8 Bit Timer Test */
946/* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */
947/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */
948 /* Bit 7.. 3: reserved */
949#define TIM_T_ON BIT_2S /* Test mode on */
950#define TIM_T_OFF BIT_1S /* Test mode off */
951#define TIM_T_STEP BIT_0S /* Test step */
952
953/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
954/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
955 /* Bit 31..24: reserved */
956#define DPT_MSK 0x00ffffffL /* Bit 23.. 0: Desc Poll Timer Bits */
957
958/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
959 /* Bit 7.. 2: reserved */
960#define DPT_START BIT_1S /* Start Descriptor Poll Timer */
961#define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */
962
963/* B2_E_3 8 bit lower 4 bits used for HW self test result */
964#define B2_E3_RES_MASK 0x0f
965
966/* B2_TST_CTRL1 8 bit Test Control Register 1 */
967#define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */
968#define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */
969#define TST_FRC_DPERR_TR BIT_5S /* force DATAPERR on TRG RD */
970#define TST_FRC_DPERR_TW BIT_4S /* force DATAPERR on TRG WR */
971#define TST_FRC_APERR_M BIT_3S /* force ADDRPERR on MST */
972#define TST_FRC_APERR_T BIT_2S /* force ADDRPERR on TRG */
973#define TST_CFG_WRITE_ON BIT_1S /* Enable Config Reg WR */
974#define TST_CFG_WRITE_OFF BIT_0S /* Disable Config Reg WR */
975
976/* B2_TST_CTRL2 8 bit Test Control Register 2 */
977 /* Bit 7.. 4: reserved */
978 /* force the following error on the next master read/write */
979#define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */
980#define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */
981#define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */
982#define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */
983
984/* B2_GP_IO 32 bit General Purpose I/O Register */
985 /* Bit 31..26: reserved */
986#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */
987#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */
988#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */
989#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=In/1=Out */
990#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=In/1=Out */
991#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=In/1=Out */
992#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=In/1=Out */
993#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=In/1=Out */
994#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=In/1=Out */
995#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=In/1=Out */
996 /* Bit 15..10: reserved */
997#define GP_IO_9 BIT_9 /* IO_9 pin */
998#define GP_IO_8 BIT_8 /* IO_8 pin */
999#define GP_IO_7 BIT_7 /* IO_7 pin */
1000#define GP_IO_6 BIT_6 /* IO_6 pin */
1001#define GP_IO_5 BIT_5 /* IO_5 pin */
1002#define GP_IO_4 BIT_4 /* IO_4 pin */
1003#define GP_IO_3 BIT_3 /* IO_3 pin */
1004#define GP_IO_2 BIT_2 /* IO_2 pin */
1005#define GP_IO_1 BIT_1 /* IO_1 pin */
1006#define GP_IO_0 BIT_0 /* IO_0 pin */
1007
1008/* B2_I2C_CTRL 32 bit I2C HW Control Register */
1009#define I2C_FLAG BIT_31 /* Start read/write if WR */
1010#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */
1011#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */
1012 /* Bit 8.. 5: reserved */
1013#define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */
1014#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */
1015#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */
1016#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */
1017#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */
1018#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */
1019#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */
1020#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */
1021#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */
1022#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */
1023#define I2C_STOP BIT_0 /* Interrupt I2C transfer */
1024
1025/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */
1026 /* Bit 31.. 1 reserved */
1027#define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */
1028
1029/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */
1030 /* Bit 7.. 3: reserved */
1031#define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */
1032#define I2C_DATA BIT_1S /* I2C Data Port */
1033#define I2C_CLK BIT_0S /* I2C Clock Port */
1034
1035/*
1036 * I2C Address
1037 */
1038#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/
1039
1040
1041/* B2_BSC_CTRL 8 bit Blink Source Counter Control */
1042 /* Bit 7.. 2: reserved */
1043#define BSC_START BIT_1S /* Start Blink Source Counter */
1044#define BSC_STOP BIT_0S /* Stop Blink Source Counter */
1045
1046/* B2_BSC_STAT 8 bit Blink Source Counter Status */
1047 /* Bit 7.. 1: reserved */
1048#define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */
1049
1050/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */
1051#define BSC_T_ON BIT_2S /* Test mode on */
1052#define BSC_T_OFF BIT_1S /* Test mode off */
1053#define BSC_T_STEP BIT_0S /* Test step */
1054
1055
1056/* B3_RAM_ADDR 32 bit RAM Address, to read or write */
1057 /* Bit 31..19: reserved */
1058#define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */
1059
1060/* RAM Interface Registers */
1061/* B3_RI_CTRL 16 bit RAM Iface Control Register */
1062 /* Bit 15..10: reserved */
1063#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */
1064#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/
1065 /* Bit 7.. 2: reserved */
1066#define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */
1067#define RI_RST_SET BIT_0S /* Set RAM Interface Reset */
1068
1069/* B3_RI_TEST 8 bit RAM Iface Test Register */
1070 /* Bit 15.. 4: reserved */
1071#define RI_T_EV BIT_3S /* Timeout Event occured */
1072#define RI_T_ON BIT_2S /* Timeout Timer Test On */
1073#define RI_T_OFF BIT_1S /* Timeout Timer Test Off */
1074#define RI_T_STEP BIT_0S /* Timeout Timer Step */
1075
1076/* MAC Arbiter Registers */
1077/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
1078 /* Bit 15.. 4: reserved */
1079#define MA_FOE_ON BIT_3S /* XMAC Fast Output Enable ON */
1080#define MA_FOE_OFF BIT_2S /* XMAC Fast Output Enable OFF */
1081#define MA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
1082#define MA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
1083
1084/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
1085 /* Bit 15.. 8: reserved */
1086#define MA_ENA_REC_TX2 BIT_7S /* Enable Recovery Timer TX2 */
1087#define MA_DIS_REC_TX2 BIT_6S /* Disable Recovery Timer TX2 */
1088#define MA_ENA_REC_TX1 BIT_5S /* Enable Recovery Timer TX1 */
1089#define MA_DIS_REC_TX1 BIT_4S /* Disable Recovery Timer TX1 */
1090#define MA_ENA_REC_RX2 BIT_3S /* Enable Recovery Timer RX2 */
1091#define MA_DIS_REC_RX2 BIT_2S /* Disable Recovery Timer RX2 */
1092#define MA_ENA_REC_RX1 BIT_1S /* Enable Recovery Timer RX1 */
1093#define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */
1094
1095/* Packet Arbiter Registers */
1096/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
1097 /* Bit 15..14: reserved */
1098#define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */
1099#define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */
1100#define PA_CLR_TO_RX2 BIT_11S /* Clear IRQ Packet Timeout RX2 */
1101#define PA_CLR_TO_RX1 BIT_10S /* Clear IRQ Packet Timeout RX1 */
1102#define PA_ENA_TO_TX2 BIT_9S /* Enable Timeout Timer TX2 */
1103#define PA_DIS_TO_TX2 BIT_8S /* Disable Timeout Timer TX2 */
1104#define PA_ENA_TO_TX1 BIT_7S /* Enable Timeout Timer TX1 */
1105#define PA_DIS_TO_TX1 BIT_6S /* Disable Timeout Timer TX1 */
1106#define PA_ENA_TO_RX2 BIT_5S /* Enable Timeout Timer RX2 */
1107#define PA_DIS_TO_RX2 BIT_4S /* Disable Timeout Timer RX2 */
1108#define PA_ENA_TO_RX1 BIT_3S /* Enable Timeout Timer RX1 */
1109#define PA_DIS_TO_RX1 BIT_2S /* Disable Timeout Timer RX1 */
1110#define PA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
1111#define PA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
1112
1113#define PA_ENA_TO_ALL (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
1114 PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
1115
1116/* Rx/Tx Path related Arbiter Test Registers */
1117/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
1118/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
1119/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
1120/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
1121#define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */
1122#define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */
1123#define TX2_T_OFF BIT_13S /* TX2 Timeout/Recv Timer Tst Off */
1124#define TX2_T_STEP BIT_12S /* TX2 Timeout/Recv Timer Step */
1125#define TX1_T_EV BIT_11S /* TX1 Timeout/Recv Event occured */
1126#define TX1_T_ON BIT_10S /* TX1 Timeout/Recv Timer Test On */
1127#define TX1_T_OFF BIT_9S /* TX1 Timeout/Recv Timer Tst Off */
1128#define TX1_T_STEP BIT_8S /* TX1 Timeout/Recv Timer Step */
1129#define RX2_T_EV BIT_7S /* RX2 Timeout/Recv Event occured */
1130#define RX2_T_ON BIT_6S /* RX2 Timeout/Recv Timer Test On */
1131#define RX2_T_OFF BIT_5S /* RX2 Timeout/Recv Timer Tst Off */
1132#define RX2_T_STEP BIT_4S /* RX2 Timeout/Recv Timer Step */
1133#define RX1_T_EV BIT_3S /* RX1 Timeout/Recv Event occured */
1134#define RX1_T_ON BIT_2S /* RX1 Timeout/Recv Timer Test On */
1135#define RX1_T_OFF BIT_1S /* RX1 Timeout/Recv Timer Tst Off */
1136#define RX1_T_STEP BIT_0S /* RX1 Timeout/Recv Timer Step */
1137
1138
1139/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
1140/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
1141/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
1142/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
1143/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */
1144 /* Bit 31..24: reserved */
1145#define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */
1146
1147/* TXA_CTRL 8 bit Tx Arbiter Control Register */
1148#define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */
1149#define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */
1150#define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */
1151#define TXA_DIS_ALLOC BIT_4S /* Disable alloc of free bandwidth */
1152#define TXA_START_RC BIT_3S /* Start sync Rate Control */
1153#define TXA_STOP_RC BIT_2S /* Stop sync Rate Control */
1154#define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */
1155#define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */
1156
1157/* TXA_TEST 8 bit Tx Arbiter Test Register */
1158 /* Bit 7.. 6: reserved */
1159#define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */
1160#define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */
1161#define TXA_INT_T_STEP BIT_3S /* Tx Arb Interval Timer Step */
1162#define TXA_LIM_T_ON BIT_2S /* Tx Arb Limit Timer Test On */
1163#define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */
1164#define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */
1165
1166/* TXA_STAT 8 bit Tx Arbiter Status Register */
1167 /* Bit 7.. 1: reserved */
1168#define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */
1169
1170/* Q_BC 32 bit Current Byte Counter */
1171 /* Bit 31..16: reserved */
1172#define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */
1173
1174/* BMU Control Status Registers */
1175/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */
1176/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */
1177/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
1178/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */
1179/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
1180/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */
1181/* Q_CSR 32 bit BMU Control/Status Register */
1182 /* Bit 31..25: reserved */
1183#define CSR_SV_IDLE BIT_24 /* BMU SM Idle */
1184 /* Bit 23..22: reserved */
1185#define CSR_DESC_CLR BIT_21 /* Clear Reset for Descr */
1186#define CSR_DESC_SET BIT_20 /* Set Reset for Descr */
1187#define CSR_FIFO_CLR BIT_19 /* Clear Reset for FIFO */
1188#define CSR_FIFO_SET BIT_18 /* Set Reset for FIFO */
1189#define CSR_HPI_RUN BIT_17 /* Release HPI SM */
1190#define CSR_HPI_RST BIT_16 /* Reset HPI SM to Idle */
1191#define CSR_SV_RUN BIT_15 /* Release Supervisor SM */
1192#define CSR_SV_RST BIT_14 /* Reset Supervisor SM */
1193#define CSR_DREAD_RUN BIT_13 /* Release Descr Read SM */
1194#define CSR_DREAD_RST BIT_12 /* Reset Descr Read SM */
1195#define CSR_DWRITE_RUN BIT_11 /* Release Descr Write SM */
1196#define CSR_DWRITE_RST BIT_10 /* Reset Descr Write SM */
1197#define CSR_TRANS_RUN BIT_9 /* Release Transfer SM */
1198#define CSR_TRANS_RST BIT_8 /* Reset Transfer SM */
1199#define CSR_ENA_POL BIT_7 /* Enable Descr Polling */
1200#define CSR_DIS_POL BIT_6 /* Disable Descr Polling */
1201#define CSR_STOP BIT_5 /* Stop Rx/Tx Queue */
1202#define CSR_START BIT_4 /* Start Rx/Tx Queue */
1203#define CSR_IRQ_CL_P BIT_3 /* (Rx) Clear Parity IRQ */
1204#define CSR_IRQ_CL_B BIT_2 /* Clear EOB IRQ */
1205#define CSR_IRQ_CL_F BIT_1 /* Clear EOF IRQ */
1206#define CSR_IRQ_CL_C BIT_0 /* Clear ERR IRQ */
1207
1208#define CSR_SET_RESET (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
1209 CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
1210 CSR_TRANS_RST)
1211#define CSR_CLR_RESET (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
1212 CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
1213 CSR_TRANS_RUN)
1214
1215/* Q_F 32 bit Flag Register */
1216 /* Bit 31..28: reserved */
1217#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */
1218#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */
1219#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */
1220#define F_WM_REACHED BIT_25 /* Watermark reached */
1221 /* reserved */
1222#define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */
1223 /* Bit 15..11: reserved */
1224#define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */
1225
1226/* Q_T1 32 bit Test Register 1 */
1227/* Holds four State Machine control Bytes */
1228#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */
1229#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */
1230#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */
1231#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */
1232
1233/* Q_T1_TR 8 bit Test Register 1 Transfer SM */
1234/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */
1235/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */
1236/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */
1237
1238/* The control status byte of each machine looks like ... */
1239#define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */
1240#define SM_LOAD BIT_3S /* Load the SM with SM_STATE */
1241#define SM_TEST_ON BIT_2S /* Switch on SM Test Mode */
1242#define SM_TEST_OFF BIT_1S /* Go off the Test Mode */
1243#define SM_STEP BIT_0S /* Step the State Machine */
1244/* The encoding of the states is not supported by the Diagnostics Tool */
1245
1246/* Q_T2 32 bit Test Register 2 */
1247 /* Bit 31.. 8: reserved */
1248#define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */
1249#define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */
1250#define T2_BC_T_ON BIT_5 /* Byte Counter Test Mode on */
1251#define T2_BC_T_OFF BIT_4 /* Byte Counter Test Mode off */
1252#define T2_STEP04 BIT_3 /* Inc AC/Dec BC by 4 */
1253#define T2_STEP03 BIT_2 /* Inc AC/Dec BC by 3 */
1254#define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */
1255#define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */
1256
1257/* Q_T3 32 bit Test Register 3 */
1258 /* Bit 31.. 7: reserved */
1259#define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */
1260 /* Bit 3: reserved */
1261#define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */
1262
1263/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
1264/* RB_START 32 bit RAM Buffer Start Address */
1265/* RB_END 32 bit RAM Buffer End Address */
1266/* RB_WP 32 bit RAM Buffer Write Pointer */
1267/* RB_RP 32 bit RAM Buffer Read Pointer */
1268/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */
1269/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */
1270/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */
1271/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */
1272/* RB_PC 32 bit RAM Buffer Packet Counter */
1273/* RB_LEV 32 bit RAM Buffer Level Register */
1274 /* Bit 31..19: reserved */
1275#define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */
1276
1277/* RB_TST2 8 bit RAM Buffer Test Register 2 */
1278 /* Bit 7.. 4: reserved */
1279#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */
1280#define RB_PC_T_ON BIT_2S /* Packet Counter Test On */
1281#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */
1282#define RB_PC_INC BIT_0S /* Packet Counter Increm */
1283
1284/* RB_TST1 8 bit RAM Buffer Test Register 1 */
1285 /* Bit 7: reserved */
1286#define RB_WP_T_ON BIT_6S /* Write Pointer Test On */
1287#define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */
1288#define RB_WP_INC BIT_4S /* Write Pointer Increm */
1289 /* Bit 3: reserved */
1290#define RB_RP_T_ON BIT_2S /* Read Pointer Test On */
1291#define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */
1292#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */
1293
1294/* RB_CTRL 8 bit RAM Buffer Control Register */
1295 /* Bit 7.. 6: reserved */
1296#define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */
1297#define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */
1298#define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */
1299#define RB_DIS_OP_MD BIT_2S /* Disable Operation Mode */
1300#define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */
1301#define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */
1302
1303
1304/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
1305
1306/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */
1307/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */
1308/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */
1309/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */
1310/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */
1311/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */
1312/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */
1313/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */
1314/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */
1315/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */
1316/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */
1317 /* Bit 31.. 6: reserved */
1318#define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */
1319
1320/* RX_MFF_CTRL1 16 bit Receive MAC FIFO Control Reg 1 */
1321 /* Bit 15..14: reserved */
1322#define MFF_ENA_RDY_PAT BIT_13S /* Enable Ready Patch */
1323#define MFF_DIS_RDY_PAT BIT_12S /* Disable Ready Patch */
1324#define MFF_ENA_TIM_PAT BIT_11S /* Enable Timing Patch */
1325#define MFF_DIS_TIM_PAT BIT_10S /* Disable Timing Patch */
1326#define MFF_ENA_ALM_FUL BIT_9S /* Enable AlmostFull Sign */
1327#define MFF_DIS_ALM_FUL BIT_8S /* Disable AlmostFull Sign */
1328#define MFF_ENA_PAUSE BIT_7S /* Enable Pause Signaling */
1329#define MFF_DIS_PAUSE BIT_6S /* Disable Pause Signaling */
1330#define MFF_ENA_FLUSH BIT_5S /* Enable Frame Flushing */
1331#define MFF_DIS_FLUSH BIT_4S /* Disable Frame Flushing */
1332#define MFF_ENA_TIST BIT_3S /* Enable Time Stamp Gener */
1333#define MFF_DIS_TIST BIT_2S /* Disable Time Stamp Gener */
1334#define MFF_CLR_INTIST BIT_1S /* Clear IRQ No Time Stamp */
1335#define MFF_CLR_INSTAT BIT_0S /* Clear IRQ No Status */
1336
1337#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
1338
1339/* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */
1340#define MFF_CLR_PERR BIT_15S /* Clear Parity Error IRQ */
1341 /* Bit 14: reserved */
1342#define MFF_ENA_PKT_REC BIT_13S /* Enable Packet Recovery */
1343#define MFF_DIS_PKT_REC BIT_12S /* Disable Packet Recovery */
1344/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1) Bit 11: Enable Timing Patch */
1345/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1) Bit 10: Disable Timing Patch */
1346/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1) Bit 9: Enable Almost Full Sign */
1347/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1) Bit 8: Disable Almost Full Sign */
1348#define MFF_ENA_W4E BIT_7S /* Enable Wait for Empty */
1349#define MFF_DIS_W4E BIT_6S /* Disable Wait for Empty */
1350/* MFF_ENA_FLUSH (see RX_MFF_CTRL1) Bit 5: Enable Frame Flushing */
1351/* MFF_DIS_FLUSH (see RX_MFF_CTRL1) Bit 4: Disable Frame Flushing */
1352#define MFF_ENA_LOOPB BIT_3S /* Enable Loopback */
1353#define MFF_DIS_LOOPB BIT_2S /* Disable Loopback */
1354#define MFF_CLR_MAC_RST BIT_1S /* Clear XMAC Reset */
1355#define MFF_SET_MAC_RST BIT_0S /* Set XMAC Reset */
1356
1357#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
1358
1359/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */
1360/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */
1361 /* Bit 7: reserved */
1362#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */
1363#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */
1364#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */
1365#define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */
1366#define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */
1367#define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */
1368#define MFF_PC_INC BIT_0S /* Packet Counter Increment */
1369
1370/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */
1371/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */
1372 /* Bit 7: reserved */
1373#define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */
1374#define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */
1375#define MFF_WP_INC BIT_4S /* Write Pointer Increm */
1376 /* Bit 3: reserved */
1377#define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */
1378#define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */
1379#define MFF_RP_DEC BIT_0S /* Read Pointer Decrement */
1380
1381/* RX_MFF_CTRL2 8 bit Receive MAC FIFO Control Reg 2 */
1382/* TX_MFF_CTRL2 8 bit Transmit MAC FIFO Control Reg 2 */
1383 /* Bit 7..4: reserved */
1384#define MFF_ENA_OP_MD BIT_3S /* Enable Operation Mode */
1385#define MFF_DIS_OP_MD BIT_2S /* Disable Operation Mode */
1386#define MFF_RST_CLR BIT_1S /* Clear MAC FIFO Reset */
1387#define MFF_RST_SET BIT_0S /* Set MAC FIFO Reset */
1388
1389
1390/* Link LED Counter Registers (GENESIS only) */
1391
1392/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */
1393/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */
1394/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */
1395 /* Bit 7.. 3: reserved */
1396#define LED_START BIT_2S /* Start Timer */
1397#define LED_STOP BIT_1S /* Stop Timer */
1398#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */
1399#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */
1400
1401/* RX_LED_TST 8 bit Receive LED Cnt Test Register */
1402/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */
1403/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */
1404 /* Bit 7.. 3: reserved */
1405#define LED_T_ON BIT_2S /* LED Counter Test mode On */
1406#define LED_T_OFF BIT_1S /* LED Counter Test mode Off */
1407#define LED_T_STEP BIT_0S /* LED Counter Step */
1408
1409/* LNK_LED_REG 8 bit Link LED Register */
1410 /* Bit 7.. 6: reserved */
1411#define LED_BLK_ON BIT_5S /* Link LED Blinking On */
1412#define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */
1413#define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */
1414#define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */
1415#define LED_ON BIT_1S /* switch LED on */
1416#define LED_OFF BIT_0S /* switch LED off */
1417
1418/* Receive and Transmit GMAC FIFO Registers (YUKON only) */
1419
1420/* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */
1421/* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */
1422/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */
1423/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */
1424/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */
1425/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */
1426/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */
1427/* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
1428/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */
1429/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */
1430/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */
1431/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */
1432/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */
1433/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */
1434
1435/* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */
1436 /* Bits 31..15: reserved */
1437#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */
1438#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */
1439#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */
1440 /* Bit 11: reserved */
1441#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */
1442#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */
1443#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */
1444#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */
1445#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */
1446#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */
1447#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */
1448#define GMF_OPER_ON BIT_3 /* Operational Mode On */
1449#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */
1450#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */
1451#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */
1452
1453/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */
1454 /* Bits 31..19: reserved */
1455#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */
1456#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */
1457#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */
1458 /* Bits 15..7: same as for RX_GMF_CTRL_T */
1459#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */
1460#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */
1461#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */
1462 /* Bits 3..0: same as for RX_GMF_CTRL_T */
1463
1464#define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON)
1465#define GMF_TX_CTRL_DEF GMF_OPER_ON
1466
1467#define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */
1468
1469/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
1470 /* Bit 7.. 3: reserved */
1471#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */
1472#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */
1473#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */
1474
1475/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */
1476 /* Bits 31.. 8: reserved */
1477#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */
1478#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */
1479#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */
1480#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */
1481#define GMC_PAUSE_ON BIT_3 /* Pause On */
1482#define GMC_PAUSE_OFF BIT_2 /* Pause Off */
1483#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */
1484#define GMC_RST_SET BIT_0 /* Set GMAC Reset */
1485
1486/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */
1487 /* Bits 31..29: reserved */
1488#define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */
1489#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */
1490#define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */
1491#define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */
1492#define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */
1493#define GPC_HWCFG_M_3 BIT_23 /* HWCFG_MODE[3] */
1494#define GPC_HWCFG_M_2 BIT_22 /* HWCFG_MODE[2] */
1495#define GPC_HWCFG_M_1 BIT_21 /* HWCFG_MODE[1] */
1496#define GPC_HWCFG_M_0 BIT_20 /* HWCFG_MODE[0] */
1497#define GPC_ANEG_0 BIT_19 /* ANEG[0] */
1498#define GPC_ENA_XC BIT_18 /* Enable MDI crossover */
1499#define GPC_DIS_125 BIT_17 /* Disable 125 MHz clock */
1500#define GPC_ANEG_3 BIT_16 /* ANEG[3] */
1501#define GPC_ANEG_2 BIT_15 /* ANEG[2] */
1502#define GPC_ANEG_1 BIT_14 /* ANEG[1] */
1503#define GPC_ENA_PAUSE BIT_13 /* Enable Pause (SYM_OR_REM) */
1504#define GPC_PHYADDR_4 BIT_12 /* Bit 4 of Phy Addr */
1505#define GPC_PHYADDR_3 BIT_11 /* Bit 3 of Phy Addr */
1506#define GPC_PHYADDR_2 BIT_10 /* Bit 2 of Phy Addr */
1507#define GPC_PHYADDR_1 BIT_9 /* Bit 1 of Phy Addr */
1508#define GPC_PHYADDR_0 BIT_8 /* Bit 0 of Phy Addr */
1509 /* Bits 7..2: reserved */
1510#define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */
1511#define GPC_RST_SET BIT_0 /* Set GPHY Reset */
1512
1513#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
1514 GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
1515
1516#define GPC_HWCFG_GMII_FIB ( GPC_HWCFG_M_2 | \
1517 GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
1518
1519#define GPC_ANEG_ADV_ALL_M (GPC_ANEG_3 | GPC_ANEG_2 | \
1520 GPC_ANEG_1 | GPC_ANEG_0)
1521
1522/* forced speed and duplex mode (don't mix with other ANEG bits) */
1523#define GPC_FRC10MBIT_HALF 0
1524#define GPC_FRC10MBIT_FULL GPC_ANEG_0
1525#define GPC_FRC100MBIT_HALF GPC_ANEG_1
1526#define GPC_FRC100MBIT_FULL (GPC_ANEG_0 | GPC_ANEG_1)
1527
1528/* auto-negotiation with limited advertised speeds */
1529/* mix only with master/slave settings (for copper) */
1530#define GPC_ADV_1000_HALF GPC_ANEG_2
1531#define GPC_ADV_1000_FULL GPC_ANEG_3
1532#define GPC_ADV_ALL (GPC_ANEG_2 | GPC_ANEG_3)
1533
1534/* master/slave settings */
1535/* only for copper with 1000 Mbps */
1536#define GPC_FORCE_MASTER 0
1537#define GPC_FORCE_SLAVE GPC_ANEG_0
1538#define GPC_PREF_MASTER GPC_ANEG_1
1539#define GPC_PREF_SLAVE (GPC_ANEG_1 | GPC_ANEG_0)
1540
1541/* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */
1542/* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */
1543#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */
1544#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */
1545#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */
1546#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */
1547#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */
1548#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */
1549
1550#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
1551 GM_IS_TX_FF_UR)
1552
1553/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
1554 /* Bits 15.. 2: reserved */
1555#define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */
1556#define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */
1557
1558
1559/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */
1560#define WOL_CTL_LINK_CHG_OCC BIT_15S
1561#define WOL_CTL_MAGIC_PKT_OCC BIT_14S
1562#define WOL_CTL_PATTERN_OCC BIT_13S
1563
1564#define WOL_CTL_CLEAR_RESULT BIT_12S
1565
1566#define WOL_CTL_ENA_PME_ON_LINK_CHG BIT_11S
1567#define WOL_CTL_DIS_PME_ON_LINK_CHG BIT_10S
1568#define WOL_CTL_ENA_PME_ON_MAGIC_PKT BIT_9S
1569#define WOL_CTL_DIS_PME_ON_MAGIC_PKT BIT_8S
1570#define WOL_CTL_ENA_PME_ON_PATTERN BIT_7S
1571#define WOL_CTL_DIS_PME_ON_PATTERN BIT_6S
1572
1573#define WOL_CTL_ENA_LINK_CHG_UNIT BIT_5S
1574#define WOL_CTL_DIS_LINK_CHG_UNIT BIT_4S
1575#define WOL_CTL_ENA_MAGIC_PKT_UNIT BIT_3S
1576#define WOL_CTL_DIS_MAGIC_PKT_UNIT BIT_2S
1577#define WOL_CTL_ENA_PATTERN_UNIT BIT_1S
1578#define WOL_CTL_DIS_PATTERN_UNIT BIT_0S
1579
1580#define WOL_CTL_DEFAULT \
1581 (WOL_CTL_DIS_PME_ON_LINK_CHG | \
1582 WOL_CTL_DIS_PME_ON_PATTERN | \
1583 WOL_CTL_DIS_PME_ON_MAGIC_PKT | \
1584 WOL_CTL_DIS_LINK_CHG_UNIT | \
1585 WOL_CTL_DIS_PATTERN_UNIT | \
1586 WOL_CTL_DIS_MAGIC_PKT_UNIT)
1587
1588/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */
1589#define WOL_CTL_PATT_ENA(x) (BIT_0 << (x))
1590
1591#define SK_NUM_WOL_PATTERN 7
1592#define SK_PATTERN_PER_WORD 4
1593#define SK_BITMASK_PATTERN 7
1594#define SK_POW_PATTERN_LENGTH 128
1595
1596#define WOL_LENGTH_MSK 0x7f
1597#define WOL_LENGTH_SHIFT 8
1598
1599
1600/* Receive and Transmit Descriptors ******************************************/
1601
1602/* Transmit Descriptor struct */
1603typedef struct s_HwTxd {
1604 SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
1605 SK_U32 TxNext; /* Physical Address Pointer to the next TxD */
1606 SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower dword */
1607 SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper dword */
1608 SK_U32 TxStat; /* Transmit Frame Status Word */
1609#ifndef SK_USE_REV_DESC
1610 SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
1611 SK_U16 TxRes1; /* 16 bit reserved field */
1612 SK_U16 TxTcpWp; /* TCP Checksum Write Position */
1613 SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
1614#else /* SK_USE_REV_DESC */
1615 SK_U16 TxRes1; /* 16 bit reserved field */
1616 SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
1617 SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
1618 SK_U16 TxTcpWp; /* TCP Checksum Write Position */
1619#endif /* SK_USE_REV_DESC */
1620 SK_U32 TxRes2; /* 32 bit reserved field */
1621} SK_HWTXD;
1622
1623/* Receive Descriptor struct */
1624typedef struct s_HwRxd {
1625 SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
1626 SK_U32 RxNext; /* Physical Address Pointer to the next RxD */
1627 SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */
1628 SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */
1629 SK_U32 RxStat; /* Receive Frame Status Word */
1630 SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */
1631#ifndef SK_USE_REV_DESC
1632 SK_U16 RxTcpSum1; /* TCP Checksum 1 */
1633 SK_U16 RxTcpSum2; /* TCP Checksum 2 */
1634 SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
1635 SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
1636#else /* SK_USE_REV_DESC */
1637 SK_U16 RxTcpSum2; /* TCP Checksum 2 */
1638 SK_U16 RxTcpSum1; /* TCP Checksum 1 */
1639 SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
1640 SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
1641#endif /* SK_USE_REV_DESC */
1642} SK_HWRXD;
1643
1644/*
1645 * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
1646 * should set the define SK_USE_REV_DESC.
1647 * Structures are 'normaly' not endianess dependent. But in
1648 * this case the SK_U16 fields are bound to bit positions inside the
1649 * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
1650 * The bit positions inside a DWord are of course endianess dependent and
1651 * swaps if the DWord is swapped by the hardware.
1652 */
1653
1654
1655/* Descriptor Bit Definition */
1656/* TxCtrl Transmit Buffer Control Field */
1657/* RxCtrl Receive Buffer Control Field */
1658#define BMU_OWN BIT_31 /* OWN bit: 0=host/1=BMU */
1659#define BMU_STF BIT_30 /* Start of Frame */
1660#define BMU_EOF BIT_29 /* End of Frame */
1661#define BMU_IRQ_EOB BIT_28 /* Req "End of Buffer" IRQ */
1662#define BMU_IRQ_EOF BIT_27 /* Req "End of Frame" IRQ */
1663/* TxCtrl specific bits */
1664#define BMU_STFWD BIT_26 /* (Tx) Store & Forward Frame */
1665#define BMU_NO_FCS BIT_25 /* (Tx) Disable MAC FCS (CRC) generation */
1666#define BMU_SW BIT_24 /* (Tx) 1 bit res. for SW use */
1667/* RxCtrl specific bits */
1668#define BMU_DEV_0 BIT_26 /* (Rx) Transfer data to Dev0 */
1669#define BMU_STAT_VAL BIT_25 /* (Rx) Rx Status Valid */
1670#define BMU_TIST_VAL BIT_24 /* (Rx) Rx TimeStamp Valid */
1671 /* Bit 23..16: BMU Check Opcodes */
1672#define BMU_CHECK (0x55L<<16) /* Default BMU check */
1673#define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */
1674#define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */
1675#define BMU_BBC 0xffffL /* Bit 15.. 0: Buffer Byte Counter */
1676
1677/* TxStat Transmit Frame Status Word */
1678/* RxStat Receive Frame Status Word */
1679/*
1680 *Note: TxStat is reserved for ASIC loopback mode only
1681 *
1682 * The Bits of the Status words are defined in xmac_ii.h
1683 * (see XMR_FS bits)
1684 */
1685
1686/* macros ********************************************************************/
1687
1688/* Receive and Transmit Queues */
1689#define Q_R1 0x0000 /* Receive Queue 1 */
1690#define Q_R2 0x0080 /* Receive Queue 2 */
1691#define Q_XS1 0x0200 /* Synchronous Transmit Queue 1 */
1692#define Q_XA1 0x0280 /* Asynchronous Transmit Queue 1 */
1693#define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */
1694#define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */
1695
1696/*
1697 * Macro Q_ADDR()
1698 *
1699 * Use this macro to access the Receive and Transmit Queue Registers.
1700 *
1701 * para:
1702 * Queue Queue to access.
1703 * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
1704 * Offs Queue register offset.
1705 * Values: Q_D, Q_DA_L ... Q_T2, Q_T3
1706 *
1707 * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
1708 */
1709#define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs))
1710
1711/*
1712 * Macro RB_ADDR()
1713 *
1714 * Use this macro to access the RAM Buffer Registers.
1715 *
1716 * para:
1717 * Queue Queue to access.
1718 * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
1719 * Offs Queue register offset.
1720 * Values: RB_START, RB_END ... RB_LEV, RB_CTRL
1721 *
1722 * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
1723 */
1724#define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs))
1725
1726
1727/* MAC Related Registers */
1728#define MAC_1 0 /* belongs to the port near the slot */
1729#define MAC_2 1 /* belongs to the port far away from the slot */
1730
1731/*
1732 * Macro MR_ADDR()
1733 *
1734 * Use this macro to access a MAC Related Registers inside the ASIC.
1735 *
1736 * para:
1737 * Mac MAC to access.
1738 * Values: MAC_1, MAC_2
1739 * Offs MAC register offset.
1740 * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
1741 * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
1742 *
1743 * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
1744 */
1745#define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs))
1746
1747#ifdef SK_LITTLE_ENDIAN
1748#define XM_WORD_LO 0
1749#define XM_WORD_HI 1
1750#else /* !SK_LITTLE_ENDIAN */
1751#define XM_WORD_LO 1
1752#define XM_WORD_HI 0
1753#endif /* !SK_LITTLE_ENDIAN */
1754
1755
1756/*
1757 * macros to access the XMAC (GENESIS only)
1758 *
1759 * XM_IN16(), to read a 16 bit register (e.g. XM_MMU_CMD)
1760 * XM_OUT16(), to write a 16 bit register (e.g. XM_MMU_CMD)
1761 * XM_IN32(), to read a 32 bit register (e.g. XM_TX_EV_CNT)
1762 * XM_OUT32(), to write a 32 bit register (e.g. XM_TX_EV_CNT)
1763 * XM_INADDR(), to read a network address register (e.g. XM_SRC_CHK)
1764 * XM_OUTADDR(), to write a network address register (e.g. XM_SRC_CHK)
1765 * XM_INHASH(), to read the XM_HSM_CHK register
1766 * XM_OUTHASH() to write the XM_HSM_CHK register
1767 *
1768 * para:
1769 * Mac XMAC to access values: MAC_1 or MAC_2
1770 * IoC I/O context needed for SK I/O macros
1771 * Reg XMAC Register to read or write
1772 * (p)Val Value or pointer to the value which should be read or written
1773 *
1774 * usage: XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
1775 */
1776
1777#define XMA(Mac, Reg) \
1778 ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
1779
1780#define XM_IN16(IoC, Mac, Reg, pVal) \
1781 SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
1782
1783#define XM_OUT16(IoC, Mac, Reg, Val) \
1784 SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
1785
1786#define XM_IN32(IoC, Mac, Reg, pVal) { \
1787 SK_IN16((IoC), XMA((Mac), (Reg)), \
1788 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
1789 SK_IN16((IoC), XMA((Mac), (Reg+2)), \
1790 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
1791}
1792
1793#define XM_OUT32(IoC, Mac, Reg, Val) { \
1794 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
1795 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
1796}
1797
1798/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
1799
1800#define XM_INADDR(IoC, Mac, Reg, pVal) { \
1801 SK_U16 Word; \
1802 SK_U8 *pByte; \
1803 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1804 SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
1805 pByte[0] = (SK_U8)(Word & 0x00ff); \
1806 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1807 SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
1808 pByte[2] = (SK_U8)(Word & 0x00ff); \
1809 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1810 SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
1811 pByte[4] = (SK_U8)(Word & 0x00ff); \
1812 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1813}
1814
1815#define XM_OUTADDR(IoC, Mac, Reg, pVal) { \
1816 SK_U8 SK_FAR *pByte; \
1817 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1818 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
1819 (((SK_U16)(pByte[0]) & 0x00ff) | \
1820 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1821 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
1822 (((SK_U16)(pByte[2]) & 0x00ff) | \
1823 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1824 SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
1825 (((SK_U16)(pByte[4]) & 0x00ff) | \
1826 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1827}
1828
1829#define XM_INHASH(IoC, Mac, Reg, pVal) { \
1830 SK_U16 Word; \
1831 SK_U8 SK_FAR *pByte; \
1832 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1833 SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
1834 pByte[0] = (SK_U8)(Word & 0x00ff); \
1835 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1836 SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
1837 pByte[2] = (SK_U8)(Word & 0x00ff); \
1838 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1839 SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
1840 pByte[4] = (SK_U8)(Word & 0x00ff); \
1841 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1842 SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word); \
1843 pByte[6] = (SK_U8)(Word & 0x00ff); \
1844 pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
1845}
1846
1847#define XM_OUTHASH(IoC, Mac, Reg, pVal) { \
1848 SK_U8 SK_FAR *pByte; \
1849 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1850 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
1851 (((SK_U16)(pByte[0]) & 0x00ff)| \
1852 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1853 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
1854 (((SK_U16)(pByte[2]) & 0x00ff)| \
1855 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1856 SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
1857 (((SK_U16)(pByte[4]) & 0x00ff)| \
1858 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1859 SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16) \
1860 (((SK_U16)(pByte[6]) & 0x00ff)| \
1861 (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
1862}
1863
1864/*
1865 * macros to access the GMAC (YUKON only)
1866 *
1867 * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT)
1868 * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL)
1869 * GM_IN32(), to read a 32 bit register (e.g. GM_)
1870 * GM_OUT32(), to write a 32 bit register (e.g. GM_)
1871 * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L)
1872 * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L)
1873 * GM_INHASH(), to read the GM_MC_ADDR_H1 register
1874 * GM_OUTHASH() to write the GM_MC_ADDR_H1 register
1875 *
1876 * para:
1877 * Mac GMAC to access values: MAC_1 or MAC_2
1878 * IoC I/O context needed for SK I/O macros
1879 * Reg GMAC Register to read or write
1880 * (p)Val Value or pointer to the value which should be read or written
1881 *
1882 * usage: GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
1883 */
1884
1885#define GMA(Mac, Reg) \
1886 ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
1887
1888#define GM_IN16(IoC, Mac, Reg, pVal) \
1889 SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
1890
1891#define GM_OUT16(IoC, Mac, Reg, Val) \
1892 SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
1893
1894#define GM_IN32(IoC, Mac, Reg, pVal) { \
1895 SK_IN16((IoC), GMA((Mac), (Reg)), \
1896 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
1897 SK_IN16((IoC), GMA((Mac), (Reg+4)), \
1898 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
1899}
1900
1901#define GM_OUT32(IoC, Mac, Reg, Val) { \
1902 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
1903 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
1904}
1905
1906#define GM_INADDR(IoC, Mac, Reg, pVal) { \
1907 SK_U16 Word; \
1908 SK_U8 *pByte; \
1909 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1910 SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
1911 pByte[0] = (SK_U8)(Word & 0x00ff); \
1912 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1913 SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
1914 pByte[2] = (SK_U8)(Word & 0x00ff); \
1915 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1916 SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
1917 pByte[4] = (SK_U8)(Word & 0x00ff); \
1918 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1919}
1920
1921#define GM_OUTADDR(IoC, Mac, Reg, pVal) { \
1922 SK_U8 SK_FAR *pByte; \
1923 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1924 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
1925 (((SK_U16)(pByte[0]) & 0x00ff) | \
1926 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1927 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
1928 (((SK_U16)(pByte[2]) & 0x00ff) | \
1929 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1930 SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
1931 (((SK_U16)(pByte[4]) & 0x00ff) | \
1932 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1933}
1934
1935#define GM_INHASH(IoC, Mac, Reg, pVal) { \
1936 SK_U16 Word; \
1937 SK_U8 *pByte; \
1938 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1939 SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
1940 pByte[0] = (SK_U8)(Word & 0x00ff); \
1941 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1942 SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
1943 pByte[2] = (SK_U8)(Word & 0x00ff); \
1944 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1945 SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
1946 pByte[4] = (SK_U8)(Word & 0x00ff); \
1947 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1948 SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \
1949 pByte[6] = (SK_U8)(Word & 0x00ff); \
1950 pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
1951}
1952
1953#define GM_OUTHASH(IoC, Mac, Reg, pVal) { \
1954 SK_U8 *pByte; \
1955 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1956 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
1957 (((SK_U16)(pByte[0]) & 0x00ff)| \
1958 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1959 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
1960 (((SK_U16)(pByte[2]) & 0x00ff)| \
1961 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1962 SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
1963 (((SK_U16)(pByte[4]) & 0x00ff)| \
1964 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1965 SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \
1966 (((SK_U16)(pByte[6]) & 0x00ff)| \
1967 (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
1968}
1969
1970/*
1971 * Different MAC Types
1972 */
1973#define SK_MAC_XMAC 0 /* Xaqti XMAC II */
1974#define SK_MAC_GMAC 1 /* Marvell GMAC */
1975
1976/*
1977 * Different PHY Types
1978 */
1979#define SK_PHY_XMAC 0 /* integrated in XMAC II */
1980#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */
1981#define SK_PHY_LONE 2 /* Level One LXT1000 */
1982#define SK_PHY_NAT 3 /* National DP83891 */
1983#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */
1984#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */
1985
1986/*
1987 * PHY addresses (bits 12..8 of PHY address reg)
1988 */
1989#define PHY_ADDR_XMAC (0<<8)
1990#define PHY_ADDR_BCOM (1<<8)
1991#define PHY_ADDR_LONE (3<<8)
1992#define PHY_ADDR_NAT (0<<8)
1993
1994/* GPHY address (bits 15..11 of SMI control reg) */
1995#define PHY_ADDR_MARV 0
1996
1997/*
1998 * macros to access the PHY
1999 *
2000 * PHY_READ() read a 16 bit value from the PHY
2001 * PHY_WRITE() write a 16 bit value to the PHY
2002 *
2003 * para:
2004 * IoC I/O context needed for SK I/O macros
2005 * pPort Pointer to port struct for PhyAddr
2006 * Mac XMAC to access values: MAC_1 or MAC_2
2007 * PhyReg PHY Register to read or write
2008 * (p)Val Value or pointer to the value which should be read or
2009 * written.
2010 *
2011 * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
2012 * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
2013 * comes back. This is checked in DEBUG mode.
2014 */
2015#ifndef DEBUG
2016#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
2017 SK_U16 Mmu; \
2018 \
2019 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2020 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2021 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2022 do { \
2023 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2024 } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
2025 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2026 } \
2027}
2028#else
2029#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
2030 SK_U16 Mmu; \
2031 int __i = 0; \
2032 \
2033 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2034 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2035 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2036 do { \
2037 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2038 __i++; \
2039 if (__i > 100000) { \
2040 SK_DBG_PRINTF("*****************************\n"); \
2041 SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \
2042 SK_DBG_PRINTF("*****************************\n"); \
2043 break; \
2044 } \
2045 } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
2046 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2047 } \
2048}
2049#endif /* DEBUG */
2050
2051#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \
2052 SK_U16 Mmu; \
2053 \
2054 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2055 do { \
2056 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2057 } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
2058 } \
2059 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2060 XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val)); \
2061 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2062 do { \
2063 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2064 } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
2065 } \
2066}
2067
2068/*
2069 * Macro PCI_C()
2070 *
2071 * Use this macro to access PCI config register from the I/O space.
2072 *
2073 * para:
2074 * Addr PCI configuration register to access.
2075 * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
2076 *
2077 * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
2078 */
2079#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */
2080
2081/*
2082 * Macro SK_HW_ADDR(Base, Addr)
2083 *
2084 * Calculates the effective HW address
2085 *
2086 * para:
2087 * Base I/O or memory base address
2088 * Addr Address offset
2089 *
2090 * usage: May be used in SK_INxx and SK_OUTxx macros
2091 * #define SK_IN8(pAC, Addr, pVal) ...\
2092 * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
2093 */
2094#ifdef SK_MEM_MAPPED_IO
2095#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
2096#else /* SK_MEM_MAPPED_IO */
2097#define SK_HW_ADDR(Base, Addr) \
2098 ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
2099#endif /* SK_MEM_MAPPED_IO */
2100
2101#define SZ_LONG (sizeof(SK_U32))
2102
2103/*
2104 * Macro SK_HWAC_LINK_LED()
2105 *
2106 * Use this macro to set the link LED mode.
2107 * para:
2108 * pAC Pointer to adapter context struct
2109 * IoC I/O context needed for SK I/O macros
2110 * Port Port number
2111 * Mode Mode to set for this LED
2112 */
2113#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
2114 SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
2115
2116
2117/* typedefs *******************************************************************/
2118
2119
2120/* function prototypes ********************************************************/
2121
2122#ifdef __cplusplus
2123}
2124#endif /* __cplusplus */
2125
2126#endif /* __INC_SKGEHW_H */
diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
deleted file mode 100644
index e6b0016a695c..000000000000
--- a/drivers/net/sk98lin/h/skgehwt.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skhwt.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2003/09/16 12:55:08 $
7 * Purpose: Defines for the hardware timer functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKGEHWT.H contains all defines and types for the timer functions
27 */
28
29#ifndef _SKGEHWT_H_
30#define _SKGEHWT_H_
31
32/*
33 * SK Hardware Timer
34 * - needed wherever the HWT module is used
35 * - use in Adapters context name pAC->Hwt
36 */
37typedef struct s_Hwt {
38 SK_U32 TStart; /* HWT start */
39 SK_U32 TStop; /* HWT stop */
40 int TActive; /* HWT: flag : active/inactive */
41} SK_HWT;
42
43extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
44extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
45extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
46extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
47extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
48#endif /* _SKGEHWT_H_ */
diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
deleted file mode 100644
index d9b6f6d8dfe2..000000000000
--- a/drivers/net/sk98lin/h/skgei2c.h
+++ /dev/null
@@ -1,210 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgei2c.h
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.25 $
6 * Date: $Date: 2003/10/20 09:06:05 $
7 * Purpose: Special defines for TWSI
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling
27 */
28
29#ifndef _INC_SKGEI2C_H_
30#define _INC_SKGEI2C_H_
31
32/*
33 * Macros to access the B2_I2C_CTRL
34 */
35#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
36 SK_OUT32(IoC, B2_I2C_CTRL,\
37 (flag ? 0x80000000UL : 0x0L) | \
38 (((SK_U32)reg << 16) & I2C_ADDR) | \
39 (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
40 (dev_size & I2C_DEV_SIZE) | \
41 ((burst << 4) & I2C_BURST_LEN))
42
43#define SK_I2C_STOP(IoC) { \
44 SK_U32 I2cCtrl; \
45 SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \
46 SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
47}
48
49#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
50
51/*
52 * Macros to access the TWSI SW Registers
53 */
54#define SK_I2C_SET_BIT(IoC, SetBits) { \
55 SK_U8 OrgBits; \
56 SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
57 SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \
58}
59
60#define SK_I2C_CLR_BIT(IoC, ClrBits) { \
61 SK_U8 OrgBits; \
62 SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
63 SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
64}
65
66#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw)
67
68/*
69 * define the possible sensor states
70 */
71#define SK_SEN_IDLE 0 /* Idle: sensor not read */
72#define SK_SEN_VALUE 1 /* Value Read cycle */
73#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */
74
75/*
76 * Conversion factor to convert read Voltage sensor to milli Volt
77 * Conversion factor to convert read Temperature sensor to 10th degree Celsius
78 */
79#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */
80#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */
81#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */
82
83/*
84 * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
85 * assuming: 6500rpm, 4 pulses, divisor 1
86 */
87#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2))
88
89/*
90 * Define sensor management data
91 * Maximum is reached on Genesis copper dual port and Yukon-64
92 * Board specific maximum is in pAC->I2c.MaxSens
93 */
94#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */
95#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */
96
97/*
98 * To watch the state machine (SM) use the timer in two ways
99 * instead of one as hitherto
100 */
101#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */
102#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */
103
104/*
105 * Defines for the individual thresholds
106 */
107
108/* Temperature sensor */
109#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */
110#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */
111#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */
112#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */
113
114/* VCC which should be 5 V */
115#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */
116#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */
117#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */
118#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */
119
120/*
121 * VIO may be 5 V or 3.3 V. Initialization takes two parts:
122 * 1. Initialize lowest lower limit and highest higher limit.
123 * 2. After the first value is read correct the upper or the lower limit to
124 * the appropriate C constant.
125 *
126 * Warning limits are +-5% of the exepected voltage.
127 * Error limits are +-10% of the expected voltage.
128 */
129
130/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
131
132#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */
133#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */
134 /* 5000 mVolt */
135#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */
136#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */
137
138#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */
139
140/* correction values for the second pass */
141#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */
142#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */
143 /* 3300 mVolt */
144#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */
145#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */
146
147/*
148 * VDD voltage
149 */
150#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */
151#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */
152#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */
153#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */
154
155/*
156 * PHY PLL 3V3 voltage
157 */
158#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */
159#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */
160#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */
161#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */
162
163/*
164 * VAUX (YUKON only)
165 */
166#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */
167#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */
168#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */
169#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */
170#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */
171#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */
172
173/*
174 * PHY 2V5 voltage
175 */
176#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */
177#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */
178#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */
179#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */
180
181/*
182 * ASIC Core 1V5 voltage (YUKON only)
183 */
184#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */
185#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */
186#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */
187#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */
188
189/*
190 * FAN 1 speed
191 */
192/* assuming: 6500rpm +-15%, 4 pulses,
193 * warning at: 80 %
194 * error at: 70 %
195 * no upper limit
196 */
197#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */
198#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */
199#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */
200#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */
201
202/*
203 * Some Voltages need dynamic thresholds
204 */
205#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */
206#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */
207#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */
208
209extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
210#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
deleted file mode 100644
index 143e635ec24d..000000000000
--- a/drivers/net/sk98lin/h/skgeinit.h
+++ /dev/null
@@ -1,797 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgeinit.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.83 $
6 * Date: $Date: 2003/09/16 14:07:37 $
7 * Purpose: Structures and prototypes for the GE Init Module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEINIT_H_
26#define __INC_SKGEINIT_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34#define SK_TEST_VAL 0x11335577UL
35
36/* modifying Link LED behaviour (used with SkGeLinkLED()) */
37#define SK_LNK_OFF LED_OFF
38#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
39#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON)
40#define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
41#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
42
43/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
44#define SK_LED_OFF LED_OFF
45#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
46#define SK_LED_STANDBY (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
47
48/* addressing LED Registers in SkGeXmitLED() */
49#define XMIT_LED_INI 0
50#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI)
51#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI)
52#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI)
53
54/* parameter 'Mode' when calling SkGeXmitLED() */
55#define SK_LED_DIS 0
56#define SK_LED_ENA 1
57#define SK_LED_TST 2
58
59/* Counter and Timer constants, for a host clock of 62.5 MHz */
60#define SK_XMIT_DUR 0x002faf08UL /* 50 ms */
61#define SK_BLK_DUR 0x01dcd650UL /* 500 ms */
62
63#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */
64
65#define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */
66 /* 215 ms at 78.12 MHz */
67
68#define SK_FACT_62 100 /* is given in percent */
69#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */
70#define SK_FACT_78 125 /* on YUKON: 78.12 MHz */
71
72/* Timeout values */
73#define SK_MAC_TO_53 72 /* MAC arbiter timeout */
74#define SK_PKT_TO_53 0x2000 /* Packet arbiter timeout */
75#define SK_PKT_TO_MAX 0xffff /* Maximum value */
76#define SK_RI_TO_53 36 /* RAM interface timeout */
77
78#define SK_PHY_ACC_TO 600000 /* PHY access timeout */
79
80/* RAM Buffer High Pause Threshold values */
81#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */
82#define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */
83#define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */
84
85#ifndef SK_BMU_RX_WM
86#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */
87#endif
88#ifndef SK_BMU_TX_WM
89#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */
90#endif
91
92/* XMAC II Rx High Watermark */
93#define SK_XM_RX_HI_WM 0x05aa /* 1450 */
94
95/* XMAC II Tx Threshold */
96#define SK_XM_THR_REDL 0x01fb /* .. for redundant link usage */
97#define SK_XM_THR_SL 0x01fb /* .. for single link adapters */
98#define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */
99#define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */
100
101/* values for GIPortUsage */
102#define SK_RED_LINK 1 /* redundant link usage */
103#define SK_MUL_LINK 2 /* multiple link usage */
104#define SK_JUMBO_LINK 3 /* driver uses jumbo frames */
105
106/* Minimum RAM Buffer Rx Queue Size */
107#define SK_MIN_RXQ_SIZE 16 /* 16 kB */
108
109/* Minimum RAM Buffer Tx Queue Size */
110#define SK_MIN_TXQ_SIZE 16 /* 16 kB */
111
112/* Queue Size units */
113#define QZ_UNITS 0x7
114#define QZ_STEP 8
115
116/* Percentage of queue size from whole memory */
117/* 80 % for receive */
118#define RAM_QUOTA_RX 80L
119/* 0% for sync transfer */
120#define RAM_QUOTA_SYNC 0L
121/* the rest (20%) is taken for async transfer */
122
123/* Get the rounded queue size in Bytes in 8k steps */
124#define ROUND_QUEUE_SIZE(SizeInBytes) \
125 ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
126 ~(QZ_STEP-1))
127
128/* Get the rounded queue size in KBytes in 8k steps */
129#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
130 ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
131
132/* Types of RAM Buffer Queues */
133#define SK_RX_SRAM_Q 1 /* small receive queue */
134#define SK_RX_BRAM_Q 2 /* big receive queue */
135#define SK_TX_RAM_Q 3 /* small or big transmit queue */
136
137/* parameter 'Dir' when calling SkGeStopPort() */
138#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */
139#define SK_STOP_RX 2 /* Stops the receive path */
140#define SK_STOP_ALL 3 /* Stops Rx and Tx path, resets the XMAC */
141
142/* parameter 'RstMode' when calling SkGeStopPort() */
143#define SK_SOFT_RST 1 /* perform a software reset */
144#define SK_HARD_RST 2 /* perform a hardware reset */
145
146/* Init Levels */
147#define SK_INIT_DATA 0 /* Init level 0: init data structures */
148#define SK_INIT_IO 1 /* Init level 1: init with IOs */
149#define SK_INIT_RUN 2 /* Init level 2: init for run time */
150
151/* Link Mode Parameter */
152#define SK_LMODE_HALF 1 /* Half Duplex Mode */
153#define SK_LMODE_FULL 2 /* Full Duplex Mode */
154#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */
155#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */
156#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */
157#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */
158#define SK_LMODE_INDETERMINATED 7 /* indeterminated */
159
160/* Auto-negotiation timeout in 100ms granularity */
161#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */
162
163/* Auto-negotiation error codes */
164#define SK_AND_OK 0 /* no error */
165#define SK_AND_OTHER 1 /* other error than below */
166#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */
167
168
169/* Link Speed Capabilities */
170#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */
171#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */
172#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */
173#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */
174#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
175
176/* Link Speed Parameter */
177#define SK_LSPEED_AUTO 1 /* Automatic resolution */
178#define SK_LSPEED_10MBPS 2 /* 10 Mbps */
179#define SK_LSPEED_100MBPS 3 /* 100 Mbps */
180#define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */
181#define SK_LSPEED_INDETERMINATED 5 /* indeterminated */
182
183/* Link Speed Current State */
184#define SK_LSPEED_STAT_UNKNOWN 1
185#define SK_LSPEED_STAT_10MBPS 2
186#define SK_LSPEED_STAT_100MBPS 3
187#define SK_LSPEED_STAT_1000MBPS 4
188#define SK_LSPEED_STAT_INDETERMINATED 5
189
190
191/* Link Capability Parameter */
192#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */
193#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */
194#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */
195#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */
196#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
197
198/* Link Mode Current State */
199#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */
200#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */
201#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */
202#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by Auto-Neg */
203#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by Auto-Neg */
204#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
205
206/* Flow Control Mode Parameter (and capabilities) */
207#define SK_FLOW_MODE_NONE 1 /* No Flow-Control */
208#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */
209#define SK_FLOW_MODE_SYMMETRIC 3 /* Both stations may send PAUSE */
210#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both stations may send PAUSE or
211 * just the remote station may send PAUSE
212 */
213#define SK_FLOW_MODE_INDETERMINATED 5 /* indeterminated */
214
215/* Flow Control Status Parameter */
216#define SK_FLOW_STAT_NONE 1 /* No Flow Control */
217#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */
218#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */
219#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */
220#define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */
221
222/* Master/Slave Mode Capabilities */
223#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */
224#define SK_MS_CAP_MASTER (1<<1) /* This station is master */
225#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */
226#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */
227
228/* Set Master/Slave Mode Parameter (and capabilities) */
229#define SK_MS_MODE_AUTO 1 /* Automatic resolution */
230#define SK_MS_MODE_MASTER 2 /* This station is master */
231#define SK_MS_MODE_SLAVE 3 /* This station is slave */
232#define SK_MS_MODE_INDETERMINATED 4 /* indeterminated */
233
234/* Master/Slave Status Parameter */
235#define SK_MS_STAT_UNSET 1 /* The M/S status is not set */
236#define SK_MS_STAT_MASTER 2 /* This station is master */
237#define SK_MS_STAT_SLAVE 3 /* This station is slave */
238#define SK_MS_STAT_FAULT 4 /* M/S resolution failed */
239#define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */
240
241/* parameter 'Mode' when calling SkXmSetRxCmd() */
242#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */
243#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */
244#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */
245#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */
246#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */
247#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */
248#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */
249#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */
250#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */
251#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */
252
253/* parameter 'Para' when calling SkMacSetRxTxEn() */
254#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */
255#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */
256#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */
257#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */
258#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */
259#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */
260
261/* States of PState */
262#define SK_PRT_RESET 0 /* the port is reset */
263#define SK_PRT_STOP 1 /* the port is stopped (similar to SW reset) */
264#define SK_PRT_INIT 2 /* the port is initialized */
265#define SK_PRT_RUN 3 /* the port has an active link */
266
267/* PHY power down modes */
268#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */
269#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */
270#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */
271#define PHY_PM_ENERGY_DETECT 3 /* energy detect */
272#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */
273
274/* Default receive frame limit for Workaround of XMAC Errata */
275#define SK_DEF_RX_WA_LIM SK_CONSTU64(100)
276
277/* values for GILedBlinkCtrl (LED Blink Control) */
278#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */
279#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */
280#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */
281
282/* Link Partner Status */
283#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */
284#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */
285#define SK_LIPA_AUTO 2 /* Link partner is in auto-negotiation state */
286
287/* Maximum Restarts before restart is ignored (3Com WA) */
288#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */
289
290/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
291#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */
292
293/* structures *****************************************************************/
294
295/*
296 * MAC specific functions
297 */
298typedef struct s_GeMacFunc {
299 int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
300 int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
301 SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
302 int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
303 int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
304 SK_U16 IStatus, SK_U64 SK_FAR *pVal);
305} SK_GEMACFUNC;
306
307/*
308 * Port Structure
309 */
310typedef struct s_GePort {
311#ifndef SK_DIAG
312 SK_TIMER PWaTimer; /* Workaround Timer */
313 SK_TIMER HalfDupChkTimer;
314#endif /* SK_DIAG */
315 SK_U32 PPrevShorts; /* Previous Short Counter checking */
316 SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */
317 SK_U64 PPrevRx; /* Previous RxOk Counter checking */
318 SK_U64 PRxLim; /* Previous RxOk Counter checking */
319 SK_U64 LastOctets; /* For half duplex hang check */
320 int PLinkResCt; /* Link Restart Counter */
321 int PAutoNegTimeOut;/* Auto-negotiation timeout current value */
322 int PAutoNegTOCt; /* Auto-negotiation Timeout Counter */
323 int PRxQSize; /* Port Rx Queue Size in kB */
324 int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */
325 int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB */
326 SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */
327 SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */
328 SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */
329 SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */
330 SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */
331 SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */
332 SK_U32 PRxOverCnt; /* Receive Overflow Counter */
333 int PRxQOff; /* Rx Queue Address Offset */
334 int PXsQOff; /* Synchronous Tx Queue Address Offset */
335 int PXaQOff; /* Asynchronous Tx Queue Address Offset */
336 int PhyType; /* PHY used on this port */
337 int PState; /* Port status (reset, stop, init, run) */
338 SK_U16 PhyId1; /* PHY Id1 on this port */
339 SK_U16 PhyAddr; /* MDIO/MDC PHY address */
340 SK_U16 PIsave; /* Saved Interrupt status word */
341 SK_U16 PSsave; /* Saved PHY status word */
342 SK_U16 PGmANegAdv; /* Saved GPhy AutoNegAdvertisment register */
343 SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */
344 SK_BOOL PLinkBroken; /* Is Link broken ? */
345 SK_BOOL PCheckPar; /* Do we check for parity errors ? */
346 SK_BOOL HalfDupTimerActive;
347 SK_U8 PLinkCap; /* Link Capabilities */
348 SK_U8 PLinkModeConf; /* Link Mode configured */
349 SK_U8 PLinkMode; /* Link Mode currently used */
350 SK_U8 PLinkModeStatus;/* Link Mode Status */
351 SK_U8 PLinkSpeedCap; /* Link Speed Capabilities(10/100/1000 Mbps) */
352 SK_U8 PLinkSpeed; /* configured Link Speed (10/100/1000 Mbps) */
353 SK_U8 PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
354 SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */
355 SK_U8 PFlowCtrlMode; /* Flow Control Mode */
356 SK_U8 PFlowCtrlStatus;/* Flow Control Status */
357 SK_U8 PMSCap; /* Master/Slave Capabilities */
358 SK_U8 PMSMode; /* Master/Slave Mode */
359 SK_U8 PMSStatus; /* Master/Slave Status */
360 SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */
361 SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */
362 SK_U8 PCableLen; /* Cable Length */
363 SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */
364 SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
365 SK_U8 PPhyPowerState; /* PHY current power state */
366 int PMacColThres; /* MAC Collision Threshold */
367 int PMacJamLen; /* MAC Jam length */
368 int PMacJamIpgVal; /* MAC Jam IPG */
369 int PMacJamIpgData; /* MAC IPG Jam to Data */
370 int PMacIpgData; /* MAC Data IPG */
371 SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */
372} SK_GEPORT;
373
374/*
375 * Gigabit Ethernet Initialization Struct
376 * (has to be included in the adapter context)
377 */
378typedef struct s_GeInit {
379 int GIChipId; /* Chip Identification Number */
380 int GIChipRev; /* Chip Revision Number */
381 SK_U8 GIPciHwRev; /* PCI HW Revision Number */
382 SK_BOOL GIGenesis; /* Genesis adapter ? */
383 SK_BOOL GIYukon; /* YUKON-A1/Bx chip */
384 SK_BOOL GIYukonLite; /* YUKON-Lite chip */
385 SK_BOOL GICopperType; /* Copper Type adapter ? */
386 SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */
387 SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */
388 SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */
389 SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */
390 SK_U16 GILedBlinkCtrl; /* LED Blink Control */
391 int GIMacsFound; /* Number of MACs found on this adapter */
392 int GIMacType; /* MAC Type used on this adapter */
393 int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */
394 int GIPortUsage; /* Driver Port Usage */
395 int GILevel; /* Initialization Level completed */
396 int GIRamSize; /* The RAM size of the adapter in kB */
397 int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */
398 SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */
399 SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
400 SK_U32 GIValIrqMask; /* Value for Interrupt Mask */
401 SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */
402 SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */
403 SK_GEMACFUNC GIFunc; /* MAC depedent functions */
404} SK_GEINIT;
405
406/*
407 * Error numbers and messages for skxmac2.c and skgeinit.c
408 */
409#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT)
410#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters"
411#define SKERR_HWI_E002 (SKERR_HWI_E001+1)
412#define SKERR_HWI_E002MSG "SkGeInit(): Level 1 call missing"
413#define SKERR_HWI_E003 (SKERR_HWI_E002+1)
414#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level"
415#define SKERR_HWI_E004 (SKERR_HWI_E003+1)
416#define SKERR_HWI_E004MSG "SkGeInitPort(): Queue Size illegal configured"
417#define SKERR_HWI_E005 (SKERR_HWI_E004+1)
418#define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports"
419#define SKERR_HWI_E006 (SKERR_HWI_E005+1)
420#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state"
421#define SKERR_HWI_E007 (SKERR_HWI_E006+1)
422#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode"
423#define SKERR_HWI_E008 (SKERR_HWI_E007+1)
424#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode"
425#define SKERR_HWI_E009 (SKERR_HWI_E008+1)
426#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero"
427#define SKERR_HWI_E010 (SKERR_HWI_E009+1)
428#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters"
429#define SKERR_HWI_E011 (SKERR_HWI_E010+1)
430#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size too small"
431#define SKERR_HWI_E012 (SKERR_HWI_E011+1)
432#define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified"
433#define SKERR_HWI_E013 (SKERR_HWI_E012+1)
434#define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue"
435#define SKERR_HWI_E014 (SKERR_HWI_E013+1)
436#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified"
437#define SKERR_HWI_E015 (SKERR_HWI_E014+1)
438#define SKERR_HWI_E015MSG "Illegal Link mode parameter"
439#define SKERR_HWI_E016 (SKERR_HWI_E015+1)
440#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter"
441#define SKERR_HWI_E017 (SKERR_HWI_E016+1)
442#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal"
443#define SKERR_HWI_E018 (SKERR_HWI_E017+1)
444#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate (Tx)"
445#define SKERR_HWI_E019 (SKERR_HWI_E018+1)
446#define SKERR_HWI_E019MSG "Illegal Speed parameter"
447#define SKERR_HWI_E020 (SKERR_HWI_E019+1)
448#define SKERR_HWI_E020MSG "Illegal Master/Slave parameter"
449#define SKERR_HWI_E021 (SKERR_HWI_E020+1)
450#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter"
451#define SKERR_HWI_E022 (SKERR_HWI_E021+1)
452#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address"
453#define SKERR_HWI_E023 (SKERR_HWI_E022+1)
454#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small"
455#define SKERR_HWI_E024 (SKERR_HWI_E023+1)
456#define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)"
457#define SKERR_HWI_E025 (SKERR_HWI_E024+1)
458#define SKERR_HWI_E025MSG ""
459
460/* function prototypes ********************************************************/
461
462#ifndef SK_KR_PROTO
463
464/*
465 * public functions in skgeinit.c
466 */
467extern void SkGePollTxD(
468 SK_AC *pAC,
469 SK_IOC IoC,
470 int Port,
471 SK_BOOL PollTxD);
472
473extern void SkGeYellowLED(
474 SK_AC *pAC,
475 SK_IOC IoC,
476 int State);
477
478extern int SkGeCfgSync(
479 SK_AC *pAC,
480 SK_IOC IoC,
481 int Port,
482 SK_U32 IntTime,
483 SK_U32 LimCount,
484 int SyncMode);
485
486extern void SkGeLoadLnkSyncCnt(
487 SK_AC *pAC,
488 SK_IOC IoC,
489 int Port,
490 SK_U32 CntVal);
491
492extern void SkGeStopPort(
493 SK_AC *pAC,
494 SK_IOC IoC,
495 int Port,
496 int Dir,
497 int RstMode);
498
499extern int SkGeInit(
500 SK_AC *pAC,
501 SK_IOC IoC,
502 int Level);
503
504extern void SkGeDeInit(
505 SK_AC *pAC,
506 SK_IOC IoC);
507
508extern int SkGeInitPort(
509 SK_AC *pAC,
510 SK_IOC IoC,
511 int Port);
512
513extern void SkGeXmitLED(
514 SK_AC *pAC,
515 SK_IOC IoC,
516 int Led,
517 int Mode);
518
519extern int SkGeInitAssignRamToQueues(
520 SK_AC *pAC,
521 int ActivePort,
522 SK_BOOL DualNet);
523
524/*
525 * public functions in skxmac2.c
526 */
527extern void SkMacRxTxDisable(
528 SK_AC *pAC,
529 SK_IOC IoC,
530 int Port);
531
532extern void SkMacSoftRst(
533 SK_AC *pAC,
534 SK_IOC IoC,
535 int Port);
536
537extern void SkMacHardRst(
538 SK_AC *pAC,
539 SK_IOC IoC,
540 int Port);
541
542extern void SkXmInitMac(
543 SK_AC *pAC,
544 SK_IOC IoC,
545 int Port);
546
547extern void SkGmInitMac(
548 SK_AC *pAC,
549 SK_IOC IoC,
550 int Port);
551
552extern void SkMacInitPhy(
553 SK_AC *pAC,
554 SK_IOC IoC,
555 int Port,
556 SK_BOOL DoLoop);
557
558extern void SkMacIrqDisable(
559 SK_AC *pAC,
560 SK_IOC IoC,
561 int Port);
562
563extern void SkMacFlushTxFifo(
564 SK_AC *pAC,
565 SK_IOC IoC,
566 int Port);
567
568extern void SkMacIrq(
569 SK_AC *pAC,
570 SK_IOC IoC,
571 int Port);
572
573extern int SkMacAutoNegDone(
574 SK_AC *pAC,
575 SK_IOC IoC,
576 int Port);
577
578extern void SkMacAutoNegLipaPhy(
579 SK_AC *pAC,
580 SK_IOC IoC,
581 int Port,
582 SK_U16 IStatus);
583
584extern int SkMacRxTxEnable(
585 SK_AC *pAC,
586 SK_IOC IoC,
587 int Port);
588
589extern void SkMacPromiscMode(
590 SK_AC *pAC,
591 SK_IOC IoC,
592 int Port,
593 SK_BOOL Enable);
594
595extern void SkMacHashing(
596 SK_AC *pAC,
597 SK_IOC IoC,
598 int Port,
599 SK_BOOL Enable);
600
601extern void SkXmPhyRead(
602 SK_AC *pAC,
603 SK_IOC IoC,
604 int Port,
605 int Addr,
606 SK_U16 SK_FAR *pVal);
607
608extern void SkXmPhyWrite(
609 SK_AC *pAC,
610 SK_IOC IoC,
611 int Port,
612 int Addr,
613 SK_U16 Val);
614
615extern void SkGmPhyRead(
616 SK_AC *pAC,
617 SK_IOC IoC,
618 int Port,
619 int Addr,
620 SK_U16 SK_FAR *pVal);
621
622extern void SkGmPhyWrite(
623 SK_AC *pAC,
624 SK_IOC IoC,
625 int Port,
626 int Addr,
627 SK_U16 Val);
628
629extern void SkXmClrExactAddr(
630 SK_AC *pAC,
631 SK_IOC IoC,
632 int Port,
633 int StartNum,
634 int StopNum);
635
636extern void SkXmAutoNegLipaXmac(
637 SK_AC *pAC,
638 SK_IOC IoC,
639 int Port,
640 SK_U16 IStatus);
641
642extern int SkXmUpdateStats(
643 SK_AC *pAC,
644 SK_IOC IoC,
645 unsigned int Port);
646
647extern int SkGmUpdateStats(
648 SK_AC *pAC,
649 SK_IOC IoC,
650 unsigned int Port);
651
652extern int SkXmMacStatistic(
653 SK_AC *pAC,
654 SK_IOC IoC,
655 unsigned int Port,
656 SK_U16 StatAddr,
657 SK_U32 SK_FAR *pVal);
658
659extern int SkGmMacStatistic(
660 SK_AC *pAC,
661 SK_IOC IoC,
662 unsigned int Port,
663 SK_U16 StatAddr,
664 SK_U32 SK_FAR *pVal);
665
666extern int SkXmResetCounter(
667 SK_AC *pAC,
668 SK_IOC IoC,
669 unsigned int Port);
670
671extern int SkGmResetCounter(
672 SK_AC *pAC,
673 SK_IOC IoC,
674 unsigned int Port);
675
676extern int SkXmOverflowStatus(
677 SK_AC *pAC,
678 SK_IOC IoC,
679 unsigned int Port,
680 SK_U16 IStatus,
681 SK_U64 SK_FAR *pStatus);
682
683extern int SkGmOverflowStatus(
684 SK_AC *pAC,
685 SK_IOC IoC,
686 unsigned int Port,
687 SK_U16 MacStatus,
688 SK_U64 SK_FAR *pStatus);
689
690extern int SkGmCableDiagStatus(
691 SK_AC *pAC,
692 SK_IOC IoC,
693 int Port,
694 SK_BOOL StartTest);
695
696#ifdef SK_DIAG
697extern void SkGePhyRead(
698 SK_AC *pAC,
699 SK_IOC IoC,
700 int Port,
701 int Addr,
702 SK_U16 *pVal);
703
704extern void SkGePhyWrite(
705 SK_AC *pAC,
706 SK_IOC IoC,
707 int Port,
708 int Addr,
709 SK_U16 Val);
710
711extern void SkMacSetRxCmd(
712 SK_AC *pAC,
713 SK_IOC IoC,
714 int Port,
715 int Mode);
716extern void SkMacCrcGener(
717 SK_AC *pAC,
718 SK_IOC IoC,
719 int Port,
720 SK_BOOL Enable);
721extern void SkMacTimeStamp(
722 SK_AC *pAC,
723 SK_IOC IoC,
724 int Port,
725 SK_BOOL Enable);
726extern void SkXmSendCont(
727 SK_AC *pAC,
728 SK_IOC IoC,
729 int Port,
730 SK_BOOL Enable);
731#endif /* SK_DIAG */
732
733#else /* SK_KR_PROTO */
734
735/*
736 * public functions in skgeinit.c
737 */
738extern void SkGePollTxD();
739extern void SkGeYellowLED();
740extern int SkGeCfgSync();
741extern void SkGeLoadLnkSyncCnt();
742extern void SkGeStopPort();
743extern int SkGeInit();
744extern void SkGeDeInit();
745extern int SkGeInitPort();
746extern void SkGeXmitLED();
747extern int SkGeInitAssignRamToQueues();
748
749/*
750 * public functions in skxmac2.c
751 */
752extern void SkMacRxTxDisable();
753extern void SkMacSoftRst();
754extern void SkMacHardRst();
755extern void SkMacInitPhy();
756extern int SkMacRxTxEnable();
757extern void SkMacPromiscMode();
758extern void SkMacHashing();
759extern void SkMacIrqDisable();
760extern void SkMacFlushTxFifo();
761extern void SkMacIrq();
762extern int SkMacAutoNegDone();
763extern void SkMacAutoNegLipaPhy();
764extern void SkXmInitMac();
765extern void SkXmPhyRead();
766extern void SkXmPhyWrite();
767extern void SkGmInitMac();
768extern void SkGmPhyRead();
769extern void SkGmPhyWrite();
770extern void SkXmClrExactAddr();
771extern void SkXmAutoNegLipaXmac();
772extern int SkXmUpdateStats();
773extern int SkGmUpdateStats();
774extern int SkXmMacStatistic();
775extern int SkGmMacStatistic();
776extern int SkXmResetCounter();
777extern int SkGmResetCounter();
778extern int SkXmOverflowStatus();
779extern int SkGmOverflowStatus();
780extern int SkGmCableDiagStatus();
781
782#ifdef SK_DIAG
783extern void SkGePhyRead();
784extern void SkGePhyWrite();
785extern void SkMacSetRxCmd();
786extern void SkMacCrcGener();
787extern void SkMacTimeStamp();
788extern void SkXmSendCont();
789#endif /* SK_DIAG */
790
791#endif /* SK_KR_PROTO */
792
793#ifdef __cplusplus
794}
795#endif /* __cplusplus */
796
797#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
deleted file mode 100644
index ddd304f1a48b..000000000000
--- a/drivers/net/sk98lin/h/skgepnm2.h
+++ /dev/null
@@ -1,334 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgepnm2.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.36 $
6 * Date: $Date: 2003/05/23 12:45:13 $
7 * Purpose: Defines for Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _SKGEPNM2_H_
26#define _SKGEPNM2_H_
27
28/*
29 * General definitions
30 */
31#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */
32#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */
33
34#define SK_PNMI_BUS_PCI 1 /* PCI bus*/
35
36/*
37 * Actions
38 */
39#define SK_PNMI_ACT_IDLE 1
40#define SK_PNMI_ACT_RESET 2
41#define SK_PNMI_ACT_SELFTEST 3
42#define SK_PNMI_ACT_RESETCNT 4
43
44/*
45 * VPD releated defines
46 */
47
48#define SK_PNMI_VPD_RW 1
49#define SK_PNMI_VPD_RO 2
50
51#define SK_PNMI_VPD_OK 0
52#define SK_PNMI_VPD_NOTFOUND 1
53#define SK_PNMI_VPD_CUT 2
54#define SK_PNMI_VPD_TIMEOUT 3
55#define SK_PNMI_VPD_FULL 4
56#define SK_PNMI_VPD_NOWRITE 5
57#define SK_PNMI_VPD_FATAL 6
58
59#define SK_PNMI_VPD_IGNORE 0
60#define SK_PNMI_VPD_CREATE 1
61#define SK_PNMI_VPD_DELETE 2
62
63
64/*
65 * RLMT related defines
66 */
67#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */
68
69
70/*
71 * VCT internal status values
72 */
73#define SK_PNMI_VCT_PENDING 32
74#define SK_PNMI_VCT_TEST_DONE 64
75#define SK_PNMI_VCT_LINK 128
76
77/*
78 * Internal table definitions
79 */
80#define SK_PNMI_GET 0
81#define SK_PNMI_PRESET 1
82#define SK_PNMI_SET 2
83
84#define SK_PNMI_RO 0
85#define SK_PNMI_RW 1
86#define SK_PNMI_WO 2
87
88typedef struct s_OidTabEntry {
89 SK_U32 Id;
90 SK_U32 InstanceNo;
91 unsigned int StructSize;
92 unsigned int Offset;
93 int Access;
94 int (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
95 SK_U32 Id, char* pBuf, unsigned int* pLen,
96 SK_U32 Instance, unsigned int TableIndex,
97 SK_U32 NetNumber);
98 SK_U16 Param;
99} SK_PNMI_TAB_ENTRY;
100
101
102/*
103 * Trap lengths
104 */
105#define SK_PNMI_TRAP_SIMPLE_LEN 17
106#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46
107#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23
108#define SK_PNMI_TRAP_RLMT_PORT_LEN 23
109
110/*
111 * Number of MAC types supported
112 */
113#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1)
114
115/*
116 * MAC statistic data list (overall set for MAC types used)
117 */
118enum SK_MACSTATS {
119 SK_PNMI_HTX = 0,
120 SK_PNMI_HTX_OCTET,
121 SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET,
122 SK_PNMI_HTX_OCTETLOW,
123 SK_PNMI_HTX_BROADCAST,
124 SK_PNMI_HTX_MULTICAST,
125 SK_PNMI_HTX_UNICAST,
126 SK_PNMI_HTX_BURST,
127 SK_PNMI_HTX_PMACC,
128 SK_PNMI_HTX_MACC,
129 SK_PNMI_HTX_COL,
130 SK_PNMI_HTX_SINGLE_COL,
131 SK_PNMI_HTX_MULTI_COL,
132 SK_PNMI_HTX_EXCESS_COL,
133 SK_PNMI_HTX_LATE_COL,
134 SK_PNMI_HTX_DEFFERAL,
135 SK_PNMI_HTX_EXCESS_DEF,
136 SK_PNMI_HTX_UNDERRUN,
137 SK_PNMI_HTX_CARRIER,
138 SK_PNMI_HTX_UTILUNDER,
139 SK_PNMI_HTX_UTILOVER,
140 SK_PNMI_HTX_64,
141 SK_PNMI_HTX_127,
142 SK_PNMI_HTX_255,
143 SK_PNMI_HTX_511,
144 SK_PNMI_HTX_1023,
145 SK_PNMI_HTX_MAX,
146 SK_PNMI_HTX_LONGFRAMES,
147 SK_PNMI_HTX_SYNC,
148 SK_PNMI_HTX_SYNC_OCTET,
149 SK_PNMI_HTX_RESERVED,
150
151 SK_PNMI_HRX,
152 SK_PNMI_HRX_OCTET,
153 SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET,
154 SK_PNMI_HRX_OCTETLOW,
155 SK_PNMI_HRX_BADOCTET,
156 SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
157 SK_PNMI_HRX_BADOCTETLOW,
158 SK_PNMI_HRX_BROADCAST,
159 SK_PNMI_HRX_MULTICAST,
160 SK_PNMI_HRX_UNICAST,
161 SK_PNMI_HRX_PMACC,
162 SK_PNMI_HRX_MACC,
163 SK_PNMI_HRX_PMACC_ERR,
164 SK_PNMI_HRX_MACC_UNKWN,
165 SK_PNMI_HRX_BURST,
166 SK_PNMI_HRX_MISSED,
167 SK_PNMI_HRX_FRAMING,
168 SK_PNMI_HRX_UNDERSIZE,
169 SK_PNMI_HRX_OVERFLOW,
170 SK_PNMI_HRX_JABBER,
171 SK_PNMI_HRX_CARRIER,
172 SK_PNMI_HRX_IRLENGTH,
173 SK_PNMI_HRX_SYMBOL,
174 SK_PNMI_HRX_SHORTS,
175 SK_PNMI_HRX_RUNT,
176 SK_PNMI_HRX_TOO_LONG,
177 SK_PNMI_HRX_FCS,
178 SK_PNMI_HRX_CEXT,
179 SK_PNMI_HRX_UTILUNDER,
180 SK_PNMI_HRX_UTILOVER,
181 SK_PNMI_HRX_64,
182 SK_PNMI_HRX_127,
183 SK_PNMI_HRX_255,
184 SK_PNMI_HRX_511,
185 SK_PNMI_HRX_1023,
186 SK_PNMI_HRX_MAX,
187 SK_PNMI_HRX_LONGFRAMES,
188
189 SK_PNMI_HRX_RESERVED,
190
191 SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
192};
193
194/*
195 * MAC specific data
196 */
197typedef struct s_PnmiStatAddr {
198 SK_U16 Reg; /* MAC register containing the value */
199 SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/
200} SK_PNMI_STATADDR;
201
202
203/*
204 * SK_PNMI_STRUCT_DATA copy offset evaluation macros
205 */
206#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
207#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
208#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
209#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
210#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
211#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
212#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
213#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
214#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
215#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
216
217#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \
218 Val32 = (s); \
219 pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
220 &(((SK_PNMI_STRUCT_DATA *)0)-> \
221 ReturnStatus.ErrorStatus)); \
222 SK_PNMI_STORE_U32(pVal, Val32); \
223 Val32 = (o); \
224 pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
225 &(((SK_PNMI_STRUCT_DATA *)0)-> \
226 ReturnStatus.ErrorOffset)); \
227 SK_PNMI_STORE_U32(pVal, Val32);}
228
229/*
230 * Time macros
231 */
232#ifndef SK_PNMI_HUNDREDS_SEC
233#if SK_TICKS_PER_SEC == 100
234#define SK_PNMI_HUNDREDS_SEC(t) (t)
235#else
236#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC))
237#endif /* !SK_TICKS_PER_SEC */
238#endif /* !SK_PNMI_HUNDREDS_SEC */
239
240/*
241 * Macros to work around alignment problems
242 */
243#ifndef SK_PNMI_STORE_U16
244#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
245 *((char *)(p) + 1) = \
246 *(((char *)&(v)) + 1);}
247#endif
248
249#ifndef SK_PNMI_STORE_U32
250#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
251 *((char *)(p) + 1) = \
252 *(((char *)&(v)) + 1); \
253 *((char *)(p) + 2) = \
254 *(((char *)&(v)) + 2); \
255 *((char *)(p) + 3) = \
256 *(((char *)&(v)) + 3);}
257#endif
258
259#ifndef SK_PNMI_STORE_U64
260#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
261 *((char *)(p) + 1) = \
262 *(((char *)&(v)) + 1); \
263 *((char *)(p) + 2) = \
264 *(((char *)&(v)) + 2); \
265 *((char *)(p) + 3) = \
266 *(((char *)&(v)) + 3); \
267 *((char *)(p) + 4) = \
268 *(((char *)&(v)) + 4); \
269 *((char *)(p) + 5) = \
270 *(((char *)&(v)) + 5); \
271 *((char *)(p) + 6) = \
272 *(((char *)&(v)) + 6); \
273 *((char *)(p) + 7) = \
274 *(((char *)&(v)) + 7);}
275#endif
276
277#ifndef SK_PNMI_READ_U16
278#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \
279 *(((char *)&(v)) + 1) = \
280 *((char *)(p) + 1);}
281#endif
282
283#ifndef SK_PNMI_READ_U32
284#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \
285 *(((char *)&(v)) + 1) = \
286 *((char *)(p) + 1); \
287 *(((char *)&(v)) + 2) = \
288 *((char *)(p) + 2); \
289 *(((char *)&(v)) + 3) = \
290 *((char *)(p) + 3);}
291#endif
292
293#ifndef SK_PNMI_READ_U64
294#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \
295 *(((char *)&(v)) + 1) = \
296 *((char *)(p) + 1); \
297 *(((char *)&(v)) + 2) = \
298 *((char *)(p) + 2); \
299 *(((char *)&(v)) + 3) = \
300 *((char *)(p) + 3); \
301 *(((char *)&(v)) + 4) = \
302 *((char *)(p) + 4); \
303 *(((char *)&(v)) + 5) = \
304 *((char *)(p) + 5); \
305 *(((char *)&(v)) + 6) = \
306 *((char *)(p) + 6); \
307 *(((char *)&(v)) + 7) = \
308 *((char *)(p) + 7);}
309#endif
310
311/*
312 * Macros for Debug
313 */
314#ifdef DEBUG
315
316#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
317 pAC->Pnmi.RlmtUpdatedFlag > 0 || \
318 pAC->Pnmi.SirqUpdatedFlag > 0) { \
319 SK_DBG_MSG(pAC, \
320 SK_DBGMOD_PNMI, \
321 SK_DBGCAT_CTRL, \
322 ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
323 vSt, \
324 pAC->Pnmi.MacUpdatedFlag, \
325 pAC->Pnmi.RlmtUpdatedFlag, \
326 pAC->Pnmi.SirqUpdatedFlag))}}
327
328#else /* !DEBUG */
329
330#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */
331
332#endif /* !DEBUG */
333
334#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
deleted file mode 100644
index 1ed214ccb253..000000000000
--- a/drivers/net/sk98lin/h/skgepnmi.h
+++ /dev/null
@@ -1,962 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgepnmi.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.62 $
6 * Date: $Date: 2003/08/15 12:31:52 $
7 * Purpose: Defines for Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _SKGEPNMI_H_
26#define _SKGEPNMI_H_
27
28/*
29 * Include dependencies
30 */
31#include "h/sktypes.h"
32#include "h/skerror.h"
33#include "h/sktimer.h"
34#include "h/ski2c.h"
35#include "h/skaddr.h"
36#include "h/skrlmt.h"
37#include "h/skvpd.h"
38
39/*
40 * Management Database Version
41 */
42#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */
43
44
45/*
46 * Event definitions
47 */
48#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */
49#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */
50#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */
51#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */
52#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */
53#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */
54#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */
55#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */
56#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */
57
58#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */
59#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */
60#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */
61#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */
62#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */
63#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets
64 1 = single net; 2 = dual net */
65#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */
66
67
68/*
69 * Return values
70 */
71#define SK_PNMI_ERR_OK 0
72#define SK_PNMI_ERR_GENERAL 1
73#define SK_PNMI_ERR_TOO_SHORT 2
74#define SK_PNMI_ERR_BAD_VALUE 3
75#define SK_PNMI_ERR_READ_ONLY 4
76#define SK_PNMI_ERR_UNKNOWN_OID 5
77#define SK_PNMI_ERR_UNKNOWN_INST 6
78#define SK_PNMI_ERR_UNKNOWN_NET 7
79#define SK_PNMI_ERR_NOT_SUPPORTED 10
80
81
82/*
83 * Return values of driver reset function SK_DRIVER_RESET() and
84 * driver event function SK_DRIVER_EVENT()
85 */
86#define SK_PNMI_ERR_OK 0
87#define SK_PNMI_ERR_FAIL 1
88
89
90/*
91 * Return values of driver test function SK_DRIVER_SELFTEST()
92 */
93#define SK_PNMI_TST_UNKNOWN (1 << 0)
94#define SK_PNMI_TST_TRANCEIVER (1 << 1)
95#define SK_PNMI_TST_ASIC (1 << 2)
96#define SK_PNMI_TST_SENSOR (1 << 3)
97#define SK_PNMI_TST_POWERMGMT (1 << 4)
98#define SK_PNMI_TST_PCI (1 << 5)
99#define SK_PNMI_TST_MAC (1 << 6)
100
101
102/*
103 * RLMT specific definitions
104 */
105#define SK_PNMI_RLMT_STATUS_STANDBY 1
106#define SK_PNMI_RLMT_STATUS_ACTIVE 2
107#define SK_PNMI_RLMT_STATUS_ERROR 3
108
109#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1
110#define SK_PNMI_RLMT_LSTAT_AUTONEG 2
111#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3
112#define SK_PNMI_RLMT_LSTAT_LOG_UP 4
113#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
114
115#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK)
116#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK)
117#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG)
118/* #define SK_PNMI_RLMT_MODE_CHK_EX */
119
120/*
121 * OID definition
122 */
123#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
124
125#define OID_GEN_XMIT_OK 0x00020101
126#define OID_GEN_RCV_OK 0x00020102
127#define OID_GEN_XMIT_ERROR 0x00020103
128#define OID_GEN_RCV_ERROR 0x00020104
129#define OID_GEN_RCV_NO_BUFFER 0x00020105
130
131/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
132#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
133/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */
134#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
135/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */
136#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
137/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */
138#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
139/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
140#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
141/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
142#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
143#define OID_GEN_RCV_CRC_ERROR 0x0002020D
144#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
145
146#define OID_802_3_PERMANENT_ADDRESS 0x01010101
147#define OID_802_3_CURRENT_ADDRESS 0x01010102
148/* #define OID_802_3_MULTICAST_LIST 0x01010103 */
149/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
150/* #define OID_802_3_MAC_OPTIONS 0x01010105 */
151
152#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
153#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
154#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
155#define OID_802_3_XMIT_DEFERRED 0x01020201
156#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
157#define OID_802_3_RCV_OVERRUN 0x01020203
158#define OID_802_3_XMIT_UNDERRUN 0x01020204
159#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
160#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
161
162/*
163 * PnP and PM OIDs
164 */
165#ifdef SK_POWER_MGMT
166#define OID_PNP_CAPABILITIES 0xFD010100
167#define OID_PNP_SET_POWER 0xFD010101
168#define OID_PNP_QUERY_POWER 0xFD010102
169#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
170#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
171#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
172#endif /* SK_POWER_MGMT */
173
174#endif /* _NDIS_ */
175
176#define OID_SKGE_MDB_VERSION 0xFF010100
177#define OID_SKGE_SUPPORTED_LIST 0xFF010101
178#define OID_SKGE_VPD_FREE_BYTES 0xFF010102
179#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103
180#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104
181#define OID_SKGE_VPD_KEY 0xFF010105
182#define OID_SKGE_VPD_VALUE 0xFF010106
183#define OID_SKGE_VPD_ACCESS 0xFF010107
184#define OID_SKGE_VPD_ACTION 0xFF010108
185
186#define OID_SKGE_PORT_NUMBER 0xFF010110
187#define OID_SKGE_DEVICE_TYPE 0xFF010111
188#define OID_SKGE_DRIVER_DESCR 0xFF010112
189#define OID_SKGE_DRIVER_VERSION 0xFF010113
190#define OID_SKGE_HW_DESCR 0xFF010114
191#define OID_SKGE_HW_VERSION 0xFF010115
192#define OID_SKGE_CHIPSET 0xFF010116
193#define OID_SKGE_ACTION 0xFF010117
194#define OID_SKGE_RESULT 0xFF010118
195#define OID_SKGE_BUS_TYPE 0xFF010119
196#define OID_SKGE_BUS_SPEED 0xFF01011A
197#define OID_SKGE_BUS_WIDTH 0xFF01011B
198/* 0xFF01011C unused */
199#define OID_SKGE_DIAG_ACTION 0xFF01011D
200#define OID_SKGE_DIAG_RESULT 0xFF01011E
201#define OID_SKGE_MTU 0xFF01011F
202#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120
203#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121
204#define OID_SKGE_PMD 0xFF010122
205#define OID_SKGE_CONNECTOR 0xFF010123
206#define OID_SKGE_LINK_CAP 0xFF010124
207#define OID_SKGE_LINK_MODE 0xFF010125
208#define OID_SKGE_LINK_MODE_STATUS 0xFF010126
209#define OID_SKGE_LINK_STATUS 0xFF010127
210#define OID_SKGE_FLOWCTRL_CAP 0xFF010128
211#define OID_SKGE_FLOWCTRL_MODE 0xFF010129
212#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A
213#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B
214#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C
215#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D
216#define OID_SKGE_MULTICAST_LIST 0xFF01012E
217#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
218
219#define OID_SKGE_TRAP 0xFF010130
220#define OID_SKGE_TRAP_NUMBER 0xFF010131
221
222#define OID_SKGE_RLMT_MODE 0xFF010140
223#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141
224#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142
225#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143
226#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160
227
228#define OID_SKGE_SPEED_CAP 0xFF010170
229#define OID_SKGE_SPEED_MODE 0xFF010171
230#define OID_SKGE_SPEED_STATUS 0xFF010172
231
232#define OID_SKGE_BOARDLEVEL 0xFF010180
233
234#define OID_SKGE_SENSOR_NUMBER 0xFF020100
235#define OID_SKGE_SENSOR_INDEX 0xFF020101
236#define OID_SKGE_SENSOR_DESCR 0xFF020102
237#define OID_SKGE_SENSOR_TYPE 0xFF020103
238#define OID_SKGE_SENSOR_VALUE 0xFF020104
239#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105
240#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106
241#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107
242#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108
243#define OID_SKGE_SENSOR_STATUS 0xFF020109
244#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A
245#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B
246#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C
247#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D
248
249#define OID_SKGE_CHKSM_NUMBER 0xFF020110
250#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111
251#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112
252#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113
253#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114
254#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115
255
256#define OID_SKGE_STAT_TX 0xFF020120
257#define OID_SKGE_STAT_TX_OCTETS 0xFF020121
258#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122
259#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123
260#define OID_SKGE_STAT_TX_UNICAST 0xFF020124
261#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125
262#define OID_SKGE_STAT_TX_BURST 0xFF020126
263#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127
264#define OID_SKGE_STAT_TX_FLOWC 0xFF020128
265#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129
266#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A
267#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B
268#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C
269#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D
270#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E
271#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F
272#define OID_SKGE_STAT_TX_CARRIER 0xFF020130
273/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */
274#define OID_SKGE_STAT_TX_64 0xFF020132
275#define OID_SKGE_STAT_TX_127 0xFF020133
276#define OID_SKGE_STAT_TX_255 0xFF020134
277#define OID_SKGE_STAT_TX_511 0xFF020135
278#define OID_SKGE_STAT_TX_1023 0xFF020136
279#define OID_SKGE_STAT_TX_MAX 0xFF020137
280#define OID_SKGE_STAT_TX_SYNC 0xFF020138
281#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139
282#define OID_SKGE_STAT_RX 0xFF02013A
283#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B
284#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C
285#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D
286#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E
287#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F
288#define OID_SKGE_STAT_RX_FLOWC 0xFF020140
289#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141
290#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142
291#define OID_SKGE_STAT_RX_BURST 0xFF020143
292#define OID_SKGE_STAT_RX_MISSED 0xFF020144
293#define OID_SKGE_STAT_RX_FRAMING 0xFF020145
294#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146
295#define OID_SKGE_STAT_RX_JABBER 0xFF020147
296#define OID_SKGE_STAT_RX_CARRIER 0xFF020148
297#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149
298#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A
299#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B
300#define OID_SKGE_STAT_RX_RUNT 0xFF02014C
301#define OID_SKGE_STAT_RX_CEXT 0xFF02014D
302#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E
303#define OID_SKGE_STAT_RX_FCS 0xFF02014F
304/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */
305#define OID_SKGE_STAT_RX_64 0xFF020151
306#define OID_SKGE_STAT_RX_127 0xFF020152
307#define OID_SKGE_STAT_RX_255 0xFF020153
308#define OID_SKGE_STAT_RX_511 0xFF020154
309#define OID_SKGE_STAT_RX_1023 0xFF020155
310#define OID_SKGE_STAT_RX_MAX 0xFF020156
311#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157
312
313#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160
314#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161
315#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162
316#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163
317
318#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164
319#define OID_SKGE_RLMT_STATUS 0xFF020165
320#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166
321#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167
322#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168
323#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169
324
325#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150
326#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151
327#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152
328#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153
329#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154
330#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155
331
332#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170
333#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171
334#define OID_SKGE_TX_RETRY 0xFF020172
335#define OID_SKGE_RX_INTR_CTS 0xFF020173
336#define OID_SKGE_TX_INTR_CTS 0xFF020174
337#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175
338#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176
339#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177
340#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178
341#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179
342#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A
343#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B
344#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C
345#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D
346#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E
347#define OID_SKGE_SYSUPTIME 0xFF02017F
348
349#define OID_SKGE_ALL_DATA 0xFF020190
350
351/* Defines for VCT. */
352#define OID_SKGE_VCT_GET 0xFF020200
353#define OID_SKGE_VCT_SET 0xFF020201
354#define OID_SKGE_VCT_STATUS 0xFF020202
355
356#ifdef SK_DIAG_SUPPORT
357/* Defines for driver DIAG mode. */
358#define OID_SKGE_DIAG_MODE 0xFF020204
359#endif /* SK_DIAG_SUPPORT */
360
361/* New OIDs */
362#define OID_SKGE_DRIVER_RELDATE 0xFF020210
363#define OID_SKGE_DRIVER_FILENAME 0xFF020211
364#define OID_SKGE_CHIPID 0xFF020212
365#define OID_SKGE_RAMSIZE 0xFF020213
366#define OID_SKGE_VAUXAVAIL 0xFF020214
367#define OID_SKGE_PHY_TYPE 0xFF020215
368#define OID_SKGE_PHY_LP_MODE 0xFF020216
369
370/* VCT struct to store a backup copy of VCT data after a port reset. */
371typedef struct s_PnmiVct {
372 SK_U8 VctStatus;
373 SK_U8 PCableLen;
374 SK_U32 PMdiPairLen[4];
375 SK_U8 PMdiPairSts[4];
376} SK_PNMI_VCT;
377
378
379/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
380#define SK_PNMI_VCT_NONE 0
381#define SK_PNMI_VCT_OLD_VCT_DATA 1
382#define SK_PNMI_VCT_NEW_VCT_DATA 2
383#define SK_PNMI_VCT_OLD_DSP_DATA 4
384#define SK_PNMI_VCT_NEW_DSP_DATA 8
385#define SK_PNMI_VCT_RUNNING 16
386
387
388/* VCT cable test status. */
389#define SK_PNMI_VCT_NORMAL_CABLE 0
390#define SK_PNMI_VCT_SHORT_CABLE 1
391#define SK_PNMI_VCT_OPEN_CABLE 2
392#define SK_PNMI_VCT_TEST_FAIL 3
393#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4
394
395#define OID_SKGE_TRAP_SEN_WAR_LOW 500
396#define OID_SKGE_TRAP_SEN_WAR_UPP 501
397#define OID_SKGE_TRAP_SEN_ERR_LOW 502
398#define OID_SKGE_TRAP_SEN_ERR_UPP 503
399#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520
400#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
401#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522
402#define OID_SKGE_TRAP_RLMT_PORT_UP 523
403#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524
404
405#ifdef SK_DIAG_SUPPORT
406/* Defines for driver DIAG mode. */
407#define SK_DIAG_ATTACHED 2
408#define SK_DIAG_RUNNING 1
409#define SK_DIAG_IDLE 0
410#endif /* SK_DIAG_SUPPORT */
411
412/*
413 * Generic PNMI IOCTL subcommand definitions.
414 */
415#define SK_GET_SINGLE_VAR 1
416#define SK_SET_SINGLE_VAR 2
417#define SK_PRESET_SINGLE_VAR 3
418#define SK_GET_FULL_MIB 4
419#define SK_SET_FULL_MIB 5
420#define SK_PRESET_FULL_MIB 6
421
422
423/*
424 * Define error numbers and messages for syslog
425 */
426#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1)
427#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID"
428#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2)
429#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys"
430#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3)
431#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID"
432#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4)
433#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action"
434#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5)
435#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver"
436#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6)
437#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command"
438#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7)
439#define SK_PNMI_ERR007MSG "General: Driver description not initialized"
440#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8)
441#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID"
442#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9)
443#define SK_PNMI_ERR009MSG "Addr: Unknown OID"
444#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10)
445#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID"
446#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11)
447#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long"
448#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12)
449#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID"
450#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13)
451#define SK_PNMI_ERR013MSG ""
452#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14)
453#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys"
454#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15)
455#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys to small"
456#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16)
457#define SK_PNMI_ERR016MSG "Vpd: Key string too long"
458#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17)
459#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer"
460#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18)
461#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid"
462#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19)
463#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long"
464#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21)
465#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long"
466#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22)
467#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before"
468#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23)
469#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action"
470#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24)
471#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action"
472#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25)
473#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry"
474#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26)
475#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD"
476#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27)
477#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry"
478#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28)
479#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry"
480#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29)
481#define SK_PNMI_ERR029MSG "General: Driver description string too long"
482#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30)
483#define SK_PNMI_ERR030MSG "General: Driver version not initialized"
484#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31)
485#define SK_PNMI_ERR031MSG "General: Driver version string too long"
486#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32)
487#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr"
488#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33)
489#define SK_PNMI_ERR033MSG "General: HW description string too long"
490#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34)
491#define SK_PNMI_ERR034MSG "General: Unknown OID"
492#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35)
493#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID"
494#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36)
495#define SK_PNMI_ERR036MSG ""
496#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37)
497#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
498#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38)
499#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
500#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39)
501#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID"
502#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40)
503#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID"
504#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41)
505#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID"
506#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42)
507#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
508#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43)
509#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
510#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44)
511#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
512#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45)
513#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
514#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46)
515#define SK_PNMI_ERR046MSG "Monitor: Unknown OID"
516#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47)
517#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returns not 0"
518#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48)
519#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0"
520#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49)
521#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
522#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50)
523#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!"
524#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51)
525#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious"
526#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52)
527#define SK_PNMI_ERR052MSG ""
528#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53)
529#define SK_PNMI_ERR053MSG "General: Driver release date not initialized"
530#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54)
531#define SK_PNMI_ERR054MSG "General: Driver release date string too long"
532#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55)
533#define SK_PNMI_ERR055MSG "General: Driver file name not initialized"
534#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56)
535#define SK_PNMI_ERR056MSG "General: Driver file name string too long"
536
537/*
538 * Management counter macros called by the driver
539 */
540#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \
541 (char *)(v))
542
543#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \
544 (char *)(v))
545
546#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \
547 (char *)(v))
548
549#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \
550 (char *)(v))
551
552#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
553 { \
554 (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
555 if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
556 (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
557 } \
558 }
559#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++)
560#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++)
561#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++)
562#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
563#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
564#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
565 ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
566#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
567 { \
568 ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
569 (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
570 }
571#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
572
573#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
574 { \
575 if ((p) < SK_MAX_MACS) { \
576 ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
577 (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
578 } \
579 }
580
581#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
582 { \
583 if ((p) < SK_MAX_MACS) { \
584 ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
585 } \
586 }
587
588#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
589 { \
590 if ((p) < SK_MAX_MACS) { \
591 ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
592 } \
593 }
594
595#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
596 { \
597 if ((p) < SK_MAX_MACS) { \
598 ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
599 } \
600 }
601
602/*
603 * Conversion Macros
604 */
605#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1)
606#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1)
607#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1)
608#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1)
609#define SK_PNMI_PORT_PHYS2INST(pAC,p) \
610 (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
611#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2)
612
613/*
614 * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
615 */
616#define SK_PNMI_VPD_KEY_SIZE 5
617#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE)
618#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4)
619#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */
620
621#define SK_PNMI_MULTICAST_LISTLEN 64
622#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS)
623#define SK_PNMI_CHECKSUM_ENTRIES 3
624#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1)
625#define SK_PNMI_MONITOR_ENTRIES 20
626#define SK_PNMI_TRAP_ENTRIES 10
627#define SK_PNMI_TRAPLEN 128
628#define SK_PNMI_STRINGLEN1 80
629#define SK_PNMI_STRINGLEN2 25
630#define SK_PNMI_TRAP_QUEUE_LEN 512
631
632typedef struct s_PnmiVpd {
633 char VpdKey[SK_PNMI_VPD_KEY_SIZE];
634 char VpdValue[SK_PNMI_VPD_DATALEN];
635 SK_U8 VpdAccess;
636 SK_U8 VpdAction;
637} SK_PNMI_VPD;
638
639typedef struct s_PnmiSensor {
640 SK_U8 SensorIndex;
641 char SensorDescr[SK_PNMI_STRINGLEN2];
642 SK_U8 SensorType;
643 SK_U32 SensorValue;
644 SK_U32 SensorWarningThresholdLow;
645 SK_U32 SensorWarningThresholdHigh;
646 SK_U32 SensorErrorThresholdLow;
647 SK_U32 SensorErrorThresholdHigh;
648 SK_U8 SensorStatus;
649 SK_U64 SensorWarningCts;
650 SK_U64 SensorErrorCts;
651 SK_U64 SensorWarningTimestamp;
652 SK_U64 SensorErrorTimestamp;
653} SK_PNMI_SENSOR;
654
655typedef struct s_PnmiChecksum {
656 SK_U64 ChecksumRxOkCts;
657 SK_U64 ChecksumRxUnableCts;
658 SK_U64 ChecksumRxErrCts;
659 SK_U64 ChecksumTxOkCts;
660 SK_U64 ChecksumTxUnableCts;
661} SK_PNMI_CHECKSUM;
662
663typedef struct s_PnmiStat {
664 SK_U64 StatTxOkCts;
665 SK_U64 StatTxOctetsOkCts;
666 SK_U64 StatTxBroadcastOkCts;
667 SK_U64 StatTxMulticastOkCts;
668 SK_U64 StatTxUnicastOkCts;
669 SK_U64 StatTxLongFramesCts;
670 SK_U64 StatTxBurstCts;
671 SK_U64 StatTxPauseMacCtrlCts;
672 SK_U64 StatTxMacCtrlCts;
673 SK_U64 StatTxSingleCollisionCts;
674 SK_U64 StatTxMultipleCollisionCts;
675 SK_U64 StatTxExcessiveCollisionCts;
676 SK_U64 StatTxLateCollisionCts;
677 SK_U64 StatTxDeferralCts;
678 SK_U64 StatTxExcessiveDeferralCts;
679 SK_U64 StatTxFifoUnderrunCts;
680 SK_U64 StatTxCarrierCts;
681 SK_U64 Dummy1; /* StatTxUtilization */
682 SK_U64 StatTx64Cts;
683 SK_U64 StatTx127Cts;
684 SK_U64 StatTx255Cts;
685 SK_U64 StatTx511Cts;
686 SK_U64 StatTx1023Cts;
687 SK_U64 StatTxMaxCts;
688 SK_U64 StatTxSyncCts;
689 SK_U64 StatTxSyncOctetsCts;
690 SK_U64 StatRxOkCts;
691 SK_U64 StatRxOctetsOkCts;
692 SK_U64 StatRxBroadcastOkCts;
693 SK_U64 StatRxMulticastOkCts;
694 SK_U64 StatRxUnicastOkCts;
695 SK_U64 StatRxLongFramesCts;
696 SK_U64 StatRxPauseMacCtrlCts;
697 SK_U64 StatRxMacCtrlCts;
698 SK_U64 StatRxPauseMacCtrlErrorCts;
699 SK_U64 StatRxMacCtrlUnknownCts;
700 SK_U64 StatRxBurstCts;
701 SK_U64 StatRxMissedCts;
702 SK_U64 StatRxFramingCts;
703 SK_U64 StatRxFifoOverflowCts;
704 SK_U64 StatRxJabberCts;
705 SK_U64 StatRxCarrierCts;
706 SK_U64 StatRxIRLengthCts;
707 SK_U64 StatRxSymbolCts;
708 SK_U64 StatRxShortsCts;
709 SK_U64 StatRxRuntCts;
710 SK_U64 StatRxCextCts;
711 SK_U64 StatRxTooLongCts;
712 SK_U64 StatRxFcsCts;
713 SK_U64 Dummy2; /* StatRxUtilization */
714 SK_U64 StatRx64Cts;
715 SK_U64 StatRx127Cts;
716 SK_U64 StatRx255Cts;
717 SK_U64 StatRx511Cts;
718 SK_U64 StatRx1023Cts;
719 SK_U64 StatRxMaxCts;
720} SK_PNMI_STAT;
721
722typedef struct s_PnmiConf {
723 char ConfMacCurrentAddr[6];
724 char ConfMacFactoryAddr[6];
725 SK_U8 ConfPMD;
726 SK_U8 ConfConnector;
727 SK_U32 ConfPhyType;
728 SK_U32 ConfPhyMode;
729 SK_U8 ConfLinkCapability;
730 SK_U8 ConfLinkMode;
731 SK_U8 ConfLinkModeStatus;
732 SK_U8 ConfLinkStatus;
733 SK_U8 ConfFlowCtrlCapability;
734 SK_U8 ConfFlowCtrlMode;
735 SK_U8 ConfFlowCtrlStatus;
736 SK_U8 ConfPhyOperationCapability;
737 SK_U8 ConfPhyOperationMode;
738 SK_U8 ConfPhyOperationStatus;
739 SK_U8 ConfSpeedCapability;
740 SK_U8 ConfSpeedMode;
741 SK_U8 ConfSpeedStatus;
742} SK_PNMI_CONF;
743
744typedef struct s_PnmiRlmt {
745 SK_U32 RlmtIndex;
746 SK_U32 RlmtStatus;
747 SK_U64 RlmtTxHelloCts;
748 SK_U64 RlmtRxHelloCts;
749 SK_U64 RlmtTxSpHelloReqCts;
750 SK_U64 RlmtRxSpHelloCts;
751} SK_PNMI_RLMT;
752
753typedef struct s_PnmiRlmtMonitor {
754 SK_U32 RlmtMonitorIndex;
755 char RlmtMonitorAddr[6];
756 SK_U64 RlmtMonitorErrorCts;
757 SK_U64 RlmtMonitorTimestamp;
758 SK_U8 RlmtMonitorAdmin;
759} SK_PNMI_RLMT_MONITOR;
760
761typedef struct s_PnmiRequestStatus {
762 SK_U32 ErrorStatus;
763 SK_U32 ErrorOffset;
764} SK_PNMI_REQUEST_STATUS;
765
766typedef struct s_PnmiStrucData {
767 SK_U32 MgmtDBVersion;
768 SK_PNMI_REQUEST_STATUS ReturnStatus;
769 SK_U32 VpdFreeBytes;
770 char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
771 SK_U32 VpdEntriesNumber;
772 SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES];
773 SK_U32 PortNumber;
774 SK_U32 DeviceType;
775 char DriverDescr[SK_PNMI_STRINGLEN1];
776 char DriverVersion[SK_PNMI_STRINGLEN2];
777 char DriverReleaseDate[SK_PNMI_STRINGLEN1];
778 char DriverFileName[SK_PNMI_STRINGLEN1];
779 char HwDescr[SK_PNMI_STRINGLEN1];
780 char HwVersion[SK_PNMI_STRINGLEN2];
781 SK_U16 Chipset;
782 SK_U32 ChipId;
783 SK_U8 VauxAvail;
784 SK_U32 RamSize;
785 SK_U32 MtuSize;
786 SK_U32 Action;
787 SK_U32 TestResult;
788 SK_U8 BusType;
789 SK_U8 BusSpeed;
790 SK_U8 BusWidth;
791 SK_U8 SensorNumber;
792 SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES];
793 SK_U8 ChecksumNumber;
794 SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES];
795 SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES];
796 SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES];
797 SK_U8 RlmtMode;
798 SK_U32 RlmtPortNumber;
799 SK_U8 RlmtPortActive;
800 SK_U8 RlmtPortPreferred;
801 SK_U64 RlmtChangeCts;
802 SK_U64 RlmtChangeTime;
803 SK_U64 RlmtChangeEstimate;
804 SK_U64 RlmtChangeThreshold;
805 SK_PNMI_RLMT Rlmt[SK_MAX_MACS];
806 SK_U32 RlmtMonitorNumber;
807 SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
808 SK_U32 TrapNumber;
809 SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN];
810 SK_U64 TxSwQueueLen;
811 SK_U64 TxSwQueueMax;
812 SK_U64 TxRetryCts;
813 SK_U64 RxIntrCts;
814 SK_U64 TxIntrCts;
815 SK_U64 RxNoBufCts;
816 SK_U64 TxNoBufCts;
817 SK_U64 TxUsedDescrNo;
818 SK_U64 RxDeliveredCts;
819 SK_U64 RxOctetsDeliveredCts;
820 SK_U64 RxHwErrorsCts;
821 SK_U64 TxHwErrorsCts;
822 SK_U64 InErrorsCts;
823 SK_U64 OutErrorsCts;
824 SK_U64 ErrRecoveryCts;
825 SK_U64 SysUpTime;
826} SK_PNMI_STRUCT_DATA;
827
828#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA))
829#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\
830 &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
831 /*
832 * ReturnStatus field
833 * must be located
834 * before VpdFreeBytes
835 */
836
837/*
838 * Various definitions
839 */
840#define SK_PNMI_MAX_PROTOS 3
841
842#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum
843 * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
844 * for check while init phase 1
845 */
846
847/*
848 * Estimate data structure
849 */
850typedef struct s_PnmiEstimate {
851 unsigned int EstValueIndex;
852 SK_U64 EstValue[7];
853 SK_U64 Estimate;
854 SK_TIMER EstTimer;
855} SK_PNMI_ESTIMATE;
856
857
858/*
859 * VCT timer data structure
860 */
861typedef struct s_VctTimer {
862 SK_TIMER VctTimer;
863} SK_PNMI_VCT_TIMER;
864
865
866/*
867 * PNMI specific adapter context structure
868 */
869typedef struct s_PnmiPort {
870 SK_U64 StatSyncCts;
871 SK_U64 StatSyncOctetsCts;
872 SK_U64 StatRxLongFrameCts;
873 SK_U64 StatRxFrameTooLongCts;
874 SK_U64 StatRxPMaccErr;
875 SK_U64 TxSwQueueLen;
876 SK_U64 TxSwQueueMax;
877 SK_U64 TxRetryCts;
878 SK_U64 RxIntrCts;
879 SK_U64 TxIntrCts;
880 SK_U64 RxNoBufCts;
881 SK_U64 TxNoBufCts;
882 SK_U64 TxUsedDescrNo;
883 SK_U64 RxDeliveredCts;
884 SK_U64 RxOctetsDeliveredCts;
885 SK_U64 RxHwErrorsCts;
886 SK_U64 TxHwErrorsCts;
887 SK_U64 InErrorsCts;
888 SK_U64 OutErrorsCts;
889 SK_U64 ErrRecoveryCts;
890 SK_U64 RxShortZeroMark;
891 SK_U64 CounterOffset[SK_PNMI_CNT_NO];
892 SK_U32 CounterHigh[SK_PNMI_CNT_NO];
893 SK_BOOL ActiveFlag;
894 SK_U8 Align[3];
895} SK_PNMI_PORT;
896
897
898typedef struct s_PnmiData {
899 SK_PNMI_PORT Port [SK_MAX_MACS];
900 SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */
901 SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO];
902 SK_U32 TestResult;
903 char HwVersion[10];
904 SK_U16 Align01;
905
906 char *pDriverDescription;
907 char *pDriverVersion;
908 char *pDriverReleaseDate;
909 char *pDriverFileName;
910
911 int MacUpdatedFlag;
912 int RlmtUpdatedFlag;
913 int SirqUpdatedFlag;
914
915 SK_U64 RlmtChangeCts;
916 SK_U64 RlmtChangeTime;
917 SK_PNMI_ESTIMATE RlmtChangeEstimate;
918 SK_U64 RlmtChangeThreshold;
919
920 SK_U64 StartUpTime;
921 SK_U32 DeviceType;
922 char PciBusSpeed;
923 char PciBusWidth;
924 char Chipset;
925 char PMD;
926 char Connector;
927 SK_BOOL DualNetActiveFlag;
928 SK_U16 Align02;
929
930 char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
931 unsigned int TrapBufFree;
932 unsigned int TrapQueueBeg;
933 unsigned int TrapQueueEnd;
934 unsigned int TrapBufPad;
935 unsigned int TrapUnique;
936 SK_U8 VctStatus[SK_MAX_MACS];
937 SK_PNMI_VCT VctBackup[SK_MAX_MACS];
938 SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
939#ifdef SK_DIAG_SUPPORT
940 SK_U32 DiagAttached;
941#endif /* SK_DIAG_SUPPORT */
942} SK_PNMI;
943
944
945/*
946 * Function prototypes
947 */
948extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level);
949extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
950 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
951extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
952 unsigned int *pLen, SK_U32 NetIndex);
953extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
954 unsigned int *pLen, SK_U32 NetIndex);
955extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
956 unsigned int *pLen, SK_U32 NetIndex);
957extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event,
958 SK_EVPARA Param);
959extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
960 unsigned int * pLen, SK_U32 NetIndex);
961
962#endif
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
deleted file mode 100644
index 3eec6274e413..000000000000
--- a/drivers/net/sk98lin/h/skgesirq.h
+++ /dev/null
@@ -1,110 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgesirq.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.30 $
6 * Date: $Date: 2003/07/04 12:34:13 $
7 * Purpose: SK specific Gigabit Ethernet special IRQ functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _INC_SKGESIRQ_H_
26#define _INC_SKGESIRQ_H_
27
28/* Define return codes of SkGePortCheckUp and CheckShort */
29#define SK_HW_PS_NONE 0 /* No action needed */
30#define SK_HW_PS_RESTART 1 /* Restart needed */
31#define SK_HW_PS_LINK 2 /* Link Up actions needed */
32
33/*
34 * Define the Event the special IRQ/INI module can handle
35 */
36#define SK_HWEV_WATIM 1 /* Timeout for WA Errata #2 XMAC */
37#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */
38#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */
39#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */
40#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */
41#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */
42#define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */
43#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */
44#define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */
45#define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */
46
47#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */
48#define SK_WA_INA_TIME (100000UL) /* 100 msec */
49
50#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */
51
52/*
53 * Define the error numbers and messages
54 */
55#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0)
56#define SKERR_SIRQ_E001MSG "Unknown event"
57#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1)
58#define SKERR_SIRQ_E002MSG "Packet timeout RX1"
59#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1)
60#define SKERR_SIRQ_E003MSG "Packet timeout RX2"
61#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1)
62#define SKERR_SIRQ_E004MSG "MAC 1 not correctly initialized"
63#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1)
64#define SKERR_SIRQ_E005MSG "MAC 2 not correctly initialized"
65#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1)
66#define SKERR_SIRQ_E006MSG "CHECK failure R1"
67#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1)
68#define SKERR_SIRQ_E007MSG "CHECK failure R2"
69#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1)
70#define SKERR_SIRQ_E008MSG "CHECK failure XS1"
71#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1)
72#define SKERR_SIRQ_E009MSG "CHECK failure XA1"
73#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1)
74#define SKERR_SIRQ_E010MSG "CHECK failure XS2"
75#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1)
76#define SKERR_SIRQ_E011MSG "CHECK failure XA2"
77#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1)
78#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error"
79#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1)
80#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error"
81#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1)
82#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)"
83#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1)
84#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)"
85#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1)
86#define SKERR_SIRQ_E016MSG "Parity error MAC 1"
87#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1)
88#define SKERR_SIRQ_E017MSG "Parity error MAC 2"
89#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1)
90#define SKERR_SIRQ_E018MSG "Parity error RX 1"
91#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1)
92#define SKERR_SIRQ_E019MSG "Parity error RX 2"
93#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1)
94#define SKERR_SIRQ_E020MSG "MAC transmit FIFO underrun"
95#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1)
96#define SKERR_SIRQ_E021MSG "Spurious TWSI interrupt"
97#define SKERR_SIRQ_E022 (SKERR_SIRQ_E021+1)
98#define SKERR_SIRQ_E022MSG "Cable pair swap error"
99#define SKERR_SIRQ_E023 (SKERR_SIRQ_E022+1)
100#define SKERR_SIRQ_E023MSG "Auto-negotiation error"
101#define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1)
102#define SKERR_SIRQ_E024MSG "FIFO overflow error"
103#define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1)
104#define SKERR_SIRQ_E025MSG "2 Pair Downshift detected"
105
106extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
107extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
108extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
109
110#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
deleted file mode 100644
index 6a63f4a15de6..000000000000
--- a/drivers/net/sk98lin/h/ski2c.h
+++ /dev/null
@@ -1,174 +0,0 @@
1/******************************************************************************
2 *
3 * Name: ski2c.h
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.35 $
6 * Date: $Date: 2003/10/20 09:06:30 $
7 * Purpose: Defines to access Voltage and Temperature Sensor
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKI2C.H contains all I2C specific defines
27 */
28
29#ifndef _SKI2C_H_
30#define _SKI2C_H_
31
32typedef struct s_Sensor SK_SENSOR;
33
34#include "h/skgei2c.h"
35
36/*
37 * Define the I2C events.
38 */
39#define SK_I2CEV_IRQ 1 /* IRQ happened Event */
40#define SK_I2CEV_TIM 2 /* Timeout event */
41#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */
42
43/*
44 * Define READ and WRITE Constants.
45 */
46#define I2C_READ 0
47#define I2C_WRITE 1
48#define I2C_BURST 1
49#define I2C_SINGLE 0
50
51#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0)
52#define SKERR_I2C_E001MSG "Sensor index unknown"
53#define SKERR_I2C_E002 (SKERR_I2C_E001+1)
54#define SKERR_I2C_E002MSG "TWSI: transfer does not complete"
55#define SKERR_I2C_E003 (SKERR_I2C_E002+1)
56#define SKERR_I2C_E003MSG "LM80: NAK on device send"
57#define SKERR_I2C_E004 (SKERR_I2C_E003+1)
58#define SKERR_I2C_E004MSG "LM80: NAK on register send"
59#define SKERR_I2C_E005 (SKERR_I2C_E004+1)
60#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send"
61#define SKERR_I2C_E006 (SKERR_I2C_E005+1)
62#define SKERR_I2C_E006MSG "Unknown event"
63#define SKERR_I2C_E007 (SKERR_I2C_E006+1)
64#define SKERR_I2C_E007MSG "LM80 read out of state"
65#define SKERR_I2C_E008 (SKERR_I2C_E007+1)
66#define SKERR_I2C_E008MSG "Unexpected sensor read completed"
67#define SKERR_I2C_E009 (SKERR_I2C_E008+1)
68#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range"
69#define SKERR_I2C_E010 (SKERR_I2C_E009+1)
70#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range"
71#define SKERR_I2C_E011 (SKERR_I2C_E010+1)
72#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range"
73#define SKERR_I2C_E012 (SKERR_I2C_E011+1)
74#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range"
75#define SKERR_I2C_E013 (SKERR_I2C_E012+1)
76#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor"
77#define SKERR_I2C_E014 (SKERR_I2C_E013+1)
78#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range"
79#define SKERR_I2C_E015 (SKERR_I2C_E014+1)
80#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range"
81#define SKERR_I2C_E016 (SKERR_I2C_E015+1)
82#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete"
83
84/*
85 * Define Timeout values
86 */
87#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */
88#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */
89#define SK_I2C_TIM_WATCH 1000000L /* 1 second */
90
91/*
92 * Define trap and error log hold times
93 */
94#ifndef SK_SEN_ERR_TR_HOLD
95#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC)
96#endif
97#ifndef SK_SEN_ERR_LOG_HOLD
98#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC)
99#endif
100#ifndef SK_SEN_WARN_TR_HOLD
101#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC)
102#endif
103#ifndef SK_SEN_WARN_LOG_HOLD
104#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC)
105#endif
106
107/*
108 * Defines for SenType
109 */
110#define SK_SEN_UNKNOWN 0
111#define SK_SEN_TEMP 1
112#define SK_SEN_VOLT 2
113#define SK_SEN_FAN 3
114
115/*
116 * Define for the SenErrorFlag
117 */
118#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */
119#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */
120#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */
121#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */
122#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */
123
124/*
125 * Define the Sensor struct
126 */
127struct s_Sensor {
128 char *SenDesc; /* Description */
129 int SenType; /* Voltage or Temperature */
130 SK_I32 SenValue; /* Current value of the sensor */
131 SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */
132 SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */
133 SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */
134 SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */
135 int SenErrFlag; /* Sensor indicated an error */
136 SK_BOOL SenInit; /* Is sensor initialized ? */
137 SK_U64 SenErrCts; /* Error trap counter */
138 SK_U64 SenWarnCts; /* Warning trap counter */
139 SK_U64 SenBegErrTS; /* Begin error timestamp */
140 SK_U64 SenBegWarnTS; /* Begin warning timestamp */
141 SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */
142 SK_U64 SenLastErrLogTS; /* Last error log timestamp */
143 SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */
144 SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */
145 int SenState; /* Sensor State (see HW specific include) */
146 int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
147 /* Sensors read function */
148 SK_U16 SenReg; /* Register Address for this sensor */
149 SK_U8 SenDev; /* Device Selection for this sensor */
150};
151
152typedef struct s_I2c {
153 SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */
154 int CurrSens; /* Which sensor is currently queried */
155 int MaxSens; /* Max. number of sensors */
156 int TimerMode; /* Use the timer also to watch the state machine */
157 int InitLevel; /* Initialized Level */
158#ifndef SK_DIAG
159 int DummyReads; /* Number of non-checked dummy reads */
160 SK_TIMER SenTimer; /* Sensors timer */
161#endif /* !SK_DIAG */
162} SK_I2C;
163
164extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
165#ifdef SK_DIAG
166extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
167 int Burst);
168#else /* !SK_DIAG */
169extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
170extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
171extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
172#endif /* !SK_DIAG */
173#endif /* n_SKI2C_H */
174
diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
deleted file mode 100644
index 2ec40d4fdf60..000000000000
--- a/drivers/net/sk98lin/h/skqueue.h
+++ /dev/null
@@ -1,94 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skqueue.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.16 $
6 * Date: $Date: 2003/09/16 12:50:32 $
7 * Purpose: Defines for the Event queue
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKQUEUE.H contains all defines and types for the event queue
27 */
28
29#ifndef _SKQUEUE_H_
30#define _SKQUEUE_H_
31
32
33/*
34 * define the event classes to be served
35 */
36#define SKGE_DRV 1 /* Driver Event Class */
37#define SKGE_RLMT 2 /* RLMT Event Class */
38#define SKGE_I2C 3 /* I2C Event Class */
39#define SKGE_PNMI 4 /* PNMI Event Class */
40#define SKGE_CSUM 5 /* Checksum Event Class */
41#define SKGE_HWAC 6 /* Hardware Access Event Class */
42
43#define SKGE_SWT 9 /* Software Timer Event Class */
44#define SKGE_LACP 10 /* LACP Aggregation Event Class */
45#define SKGE_RSF 11 /* RSF Aggregation Event Class */
46#define SKGE_MARKER 12 /* MARKER Aggregation Event Class */
47#define SKGE_FD 13 /* FD Distributor Event Class */
48
49/*
50 * define event queue as circular buffer
51 */
52#define SK_MAX_EVENT 64
53
54/*
55 * Parameter union for the Para stuff
56 */
57typedef union u_EvPara {
58 void *pParaPtr; /* Parameter Pointer */
59 SK_U64 Para64; /* Parameter 64bit version */
60 SK_U32 Para32[2]; /* Parameter Array of 32bit parameters */
61} SK_EVPARA;
62
63/*
64 * Event Queue
65 * skqueue.c
66 * events are class/value pairs
67 * class is addressee, e.g. RLMT, PNMI etc.
68 * value is command, e.g. line state change, ring op change etc.
69 */
70typedef struct s_EventElem {
71 SK_U32 Class; /* Event class */
72 SK_U32 Event; /* Event value */
73 SK_EVPARA Para; /* Event parameter */
74} SK_EVENTELEM;
75
76typedef struct s_Queue {
77 SK_EVENTELEM EvQueue[SK_MAX_EVENT];
78 SK_EVENTELEM *EvPut;
79 SK_EVENTELEM *EvGet;
80} SK_QUEUE;
81
82extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
83extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
84 SK_EVPARA Para);
85extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
86
87
88/* Define Error Numbers and messages */
89#define SKERR_Q_E001 (SK_ERRBASE_QUEUE+0)
90#define SKERR_Q_E001MSG "Event queue overflow"
91#define SKERR_Q_E002 (SKERR_Q_E001+1)
92#define SKERR_Q_E002MSG "Undefined event class"
93#endif /* _SKQUEUE_H_ */
94
diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
deleted file mode 100644
index ca75dfdcf2d6..000000000000
--- a/drivers/net/sk98lin/h/skrlmt.h
+++ /dev/null
@@ -1,438 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skrlmt.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.37 $
6 * Date: $Date: 2003/04/15 09:43:43 $
7 * Purpose: Header file for Redundant Link ManagemenT.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the header file for Redundant Link ManagemenT.
30 *
31 * Include File Hierarchy:
32 *
33 * "skdrv1st.h"
34 * ...
35 * "sktypes.h"
36 * "skqueue.h"
37 * "skaddr.h"
38 * "skrlmt.h"
39 * ...
40 * "skdrv2nd.h"
41 *
42 ******************************************************************************/
43
44#ifndef __INC_SKRLMT_H
45#define __INC_SKRLMT_H
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51/* defines ********************************************************************/
52
53#define SK_RLMT_NET_DOWN_TEMP 1 /* NET_DOWN due to last port down. */
54#define SK_RLMT_NET_DOWN_FINAL 2 /* NET_DOWN due to RLMT_STOP. */
55
56/* ----- Default queue sizes - must be multiples of 8 KB ----- */
57
58/* Less than 8 KB free in RX queue => pause frames. */
59#define SK_RLMT_STANDBY_QRXSIZE 128 /* Size of rx standby queue in KB. */
60#define SK_RLMT_STANDBY_QXASIZE 32 /* Size of async standby queue in KB. */
61#define SK_RLMT_STANDBY_QXSSIZE 0 /* Size of sync standby queue in KB. */
62
63#define SK_RLMT_MAX_TX_BUF_SIZE 60 /* Maximum RLMT transmit size. */
64
65/* ----- PORT states ----- */
66
67#define SK_RLMT_PS_INIT 0 /* Port state: Init. */
68#define SK_RLMT_PS_LINK_DOWN 1 /* Port state: Link down. */
69#define SK_RLMT_PS_DOWN 2 /* Port state: Port down. */
70#define SK_RLMT_PS_GOING_UP 3 /* Port state: Going up. */
71#define SK_RLMT_PS_UP 4 /* Port state: Up. */
72
73/* ----- RLMT states ----- */
74
75#define SK_RLMT_RS_INIT 0 /* RLMT state: Init. */
76#define SK_RLMT_RS_NET_DOWN 1 /* RLMT state: Net down. */
77#define SK_RLMT_RS_NET_UP 2 /* RLMT state: Net up. */
78
79/* ----- PORT events ----- */
80
81#define SK_RLMT_LINK_UP 1001 /* Link came up. */
82#define SK_RLMT_LINK_DOWN 1002 /* Link went down. */
83#define SK_RLMT_PORT_ADDR 1003 /* Port address changed. */
84
85/* ----- RLMT events ----- */
86
87#define SK_RLMT_START 2001 /* Start RLMT. */
88#define SK_RLMT_STOP 2002 /* Stop RLMT. */
89#define SK_RLMT_PACKET_RECEIVED 2003 /* Packet was received for RLMT. */
90#define SK_RLMT_STATS_CLEAR 2004 /* Clear statistics. */
91#define SK_RLMT_STATS_UPDATE 2005 /* Update statistics. */
92#define SK_RLMT_PREFPORT_CHANGE 2006 /* Change preferred port. */
93#define SK_RLMT_MODE_CHANGE 2007 /* New RlmtMode. */
94#define SK_RLMT_SET_NETS 2008 /* Number of Nets (1 or 2). */
95
96/* ----- RLMT mode bits ----- */
97
98/*
99 * CAUTION: These defines are private to RLMT.
100 * Please use the RLMT mode defines below.
101 */
102
103#define SK_RLMT_CHECK_LINK 1 /* Check Link. */
104#define SK_RLMT_CHECK_LOC_LINK 2 /* Check other link on same adapter. */
105#define SK_RLMT_CHECK_SEG 4 /* Check segmentation. */
106
107#ifndef RLMT_CHECK_REMOTE
108#define SK_RLMT_CHECK_OTHERS SK_RLMT_CHECK_LOC_LINK
109#else /* RLMT_CHECK_REMOTE */
110#define SK_RLMT_CHECK_REM_LINK 8 /* Check link(s) on other adapter(s). */
111#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED 3
112#define SK_RLMT_CHECK_OTHERS \
113 (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
114#endif /* RLMT_CHECK_REMOTE */
115
116#ifndef SK_RLMT_ENABLE_TRANSPARENT
117#define SK_RLMT_TRANSPARENT 0 /* RLMT transparent - inactive. */
118#else /* SK_RLMT_ENABLE_TRANSPARENT */
119#define SK_RLMT_TRANSPARENT 128 /* RLMT transparent. */
120#endif /* SK_RLMT_ENABLE_TRANSPARENT */
121
122/* ----- RLMT modes ----- */
123
124/* Check Link State. */
125#define SK_RLMT_MODE_CLS (SK_RLMT_CHECK_LINK)
126
127/* Check Local Ports: check other links on the same adapter. */
128#define SK_RLMT_MODE_CLP (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
129
130/* Check Local Ports and Segmentation Status. */
131#define SK_RLMT_MODE_CLPSS \
132 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
133
134#ifdef RLMT_CHECK_REMOTE
135/* Check Local and Remote Ports: check links (local or remote). */
136 Name of define TBD!
137#define SK_RLMT_MODE_CRP \
138 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
139
140/* Check Local and Remote Ports and Segmentation Status. */
141 Name of define TBD!
142#define SK_RLMT_MODE_CRPSS \
143 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
144 SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
145#endif /* RLMT_CHECK_REMOTE */
146
147/* ----- RLMT lookahead result bits ----- */
148
149#define SK_RLMT_RX_RLMT 1 /* Give packet to RLMT. */
150#define SK_RLMT_RX_PROTOCOL 2 /* Give packet to protocol. */
151
152/* Macros */
153
154#if 0
155SK_AC *pAC /* adapter context */
156SK_U32 PortNum /* receiving port */
157unsigned PktLen /* received packet's length */
158SK_BOOL IsBc /* Flag: packet is broadcast */
159unsigned *pOffset /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
160unsigned *pNumBytes /* #Bytes to present to SK_RLMT_LOOKAHEAD */
161#endif /* 0 */
162
163#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
164 SK_AC *_pAC; \
165 SK_U32 _PortNum; \
166 _pAC = (pAC); \
167 _PortNum = (SK_U32)(PortNum); \
168 /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
169 _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
170 if (_pAC->Rlmt.RlmtOff) { \
171 *(pNumBytes) = 0; \
172 } \
173 else {\
174 if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
175 *(pNumBytes) = 0; \
176 } \
177 else if (IsBc) { \
178 if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
179 *(pNumBytes) = 6; \
180 *(pOffset) = 6; \
181 } \
182 else { \
183 *(pNumBytes) = 0; \
184 } \
185 } \
186 else { \
187 if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
188 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
189 *(pNumBytes) = 0; \
190 } \
191 else { \
192 *(pNumBytes) = 6; \
193 *(pOffset) = 0; \
194 } \
195 } \
196 } \
197}
198
199#if 0
200SK_AC *pAC /* adapter context */
201SK_U32 PortNum /* receiving port */
202SK_U8 *pLaPacket, /* received packet's data (points to pOffset) */
203SK_BOOL IsBc /* Flag: packet is broadcast */
204SK_BOOL IsMc /* Flag: packet is multicast */
205unsigned *pForRlmt /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
206SK_RLMT_LOOKAHEAD() expects *pNumBytes from
207packet offset *pOffset (s.a.) at *pLaPacket.
208
209If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
210BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
211can trash unneeded parts of the if construction.
212#endif /* 0 */
213
214#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
215 SK_AC *_pAC; \
216 SK_U32 _PortNum; \
217 SK_U8 *_pLaPacket; \
218 _pAC = (pAC); \
219 _PortNum = (SK_U32)(PortNum); \
220 _pLaPacket = (SK_U8 *)(pLaPacket); \
221 if (IsBc) {\
222 if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
223 _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
224 _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
225 _pAC->Rlmt.CheckSwitch = SK_TRUE; \
226 } \
227 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
228 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
229 } \
230 else if (IsMc) { \
231 if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
232 _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
233 if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
234 *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
235 } \
236 else { \
237 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
238 } \
239 } \
240 else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
241 *(pForRlmt) = SK_RLMT_RX_RLMT; \
242 } \
243 else { \
244 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
245 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
246 } \
247 } \
248 else { \
249 if (SK_ADDR_EQUAL( \
250 _pLaPacket, \
251 _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
252 *(pForRlmt) = SK_RLMT_RX_RLMT; \
253 } \
254 else { \
255 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
256 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
257 } \
258 } \
259}
260
261#ifdef SK_RLMT_FAST_LOOKAHEAD
262Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
263#endif /* SK_RLMT_FAST_LOOKAHEAD */
264#ifdef SK_RLMT_SLOW_LOOKAHEAD
265Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
266#endif /* SK_RLMT_SLOW_LOOKAHEAD */
267
268/* typedefs *******************************************************************/
269
270#ifdef SK_RLMT_MBUF_PRIVATE
271typedef struct s_RlmtMbuf {
272 some content
273} SK_RLMT_MBUF;
274#endif /* SK_RLMT_MBUF_PRIVATE */
275
276
277#ifdef SK_LA_INFO
278typedef struct s_Rlmt_PacketInfo {
279 unsigned PacketLength; /* Length of packet. */
280 unsigned PacketType; /* Directed/Multicast/Broadcast. */
281} SK_RLMT_PINFO;
282#endif /* SK_LA_INFO */
283
284
285typedef struct s_RootId {
286 SK_U8 Id[8]; /* Root Bridge Id. */
287} SK_RLMT_ROOT_ID;
288
289
290typedef struct s_port {
291 SK_MAC_ADDR CheckAddr;
292 SK_BOOL SuspectTx;
293} SK_PORT_CHECK;
294
295
296typedef struct s_RlmtNet SK_RLMT_NET;
297
298
299typedef struct s_RlmtPort {
300
301/* ----- Public part (read-only) ----- */
302
303 SK_U8 PortState; /* Current state of this port. */
304
305 /* For PNMI */
306 SK_BOOL LinkDown;
307 SK_BOOL PortDown;
308 SK_U8 Align01;
309
310 SK_U32 PortNumber; /* Number of port on adapter. */
311 SK_RLMT_NET * Net; /* Net port belongs to. */
312
313 SK_U64 TxHelloCts;
314 SK_U64 RxHelloCts;
315 SK_U64 TxSpHelloReqCts;
316 SK_U64 RxSpHelloCts;
317
318/* ----- Private part ----- */
319
320/* SK_U64 PacketsRx; */ /* Total packets received. */
321 SK_U32 PacketsPerTimeSlot; /* Packets rxed between TOs. */
322/* SK_U32 DataPacketsPerTimeSlot; */ /* Data packets ... */
323 SK_U32 BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
324 SK_U64 BcTimeStamp; /* Time of last BC receive. */
325 SK_U64 GuTimeStamp; /* Time of entering GOING_UP. */
326
327 SK_TIMER UpTimer; /* Timer struct Link/Port up. */
328 SK_TIMER DownRxTimer; /* Timer struct down rx. */
329 SK_TIMER DownTxTimer; /* Timer struct down tx. */
330
331 SK_U32 CheckingState; /* Checking State. */
332
333 SK_ADDR_PORT * AddrPort;
334
335 SK_U8 Random[4]; /* Random value. */
336 unsigned PortsChecked; /* #ports checked. */
337 unsigned PortsSuspect; /* #ports checked that are s. */
338 SK_PORT_CHECK PortCheck[1];
339/* SK_PORT_CHECK PortCheck[SK_MAX_MACS - 1]; */
340
341 SK_BOOL PortStarted; /* Port is started. */
342 SK_BOOL PortNoRx; /* NoRx for >= 1 time slot. */
343 SK_BOOL RootIdSet;
344 SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
345} SK_RLMT_PORT;
346
347
348struct s_RlmtNet {
349
350/* ----- Public part (read-only) ----- */
351
352 SK_U32 NetNumber; /* Number of net. */
353
354 SK_RLMT_PORT * Port[SK_MAX_MACS]; /* Ports that belong to this net. */
355 SK_U32 NumPorts; /* Number of ports. */
356 SK_U32 PrefPort; /* Preferred port. */
357
358 /* For PNMI */
359
360 SK_U32 ChgBcPrio; /* Change Priority of last broadcast received */
361 SK_U32 RlmtMode; /* Check ... */
362 SK_U32 ActivePort; /* Active port. */
363 SK_U32 Preference; /* 0xFFFFFFFF: Automatic. */
364
365 SK_U8 RlmtState; /* Current RLMT state. */
366
367/* ----- Private part ----- */
368 SK_BOOL RootIdSet;
369 SK_U16 Align01;
370
371 int LinksUp; /* #Links up. */
372 int PortsUp; /* #Ports up. */
373 SK_U32 TimeoutValue; /* RLMT timeout value. */
374
375 SK_U32 CheckingState; /* Checking State. */
376 SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
377
378 SK_TIMER LocTimer; /* Timer struct. */
379 SK_TIMER SegTimer; /* Timer struct. */
380};
381
382
383typedef struct s_Rlmt {
384
385/* ----- Public part (read-only) ----- */
386
387 SK_U32 NumNets; /* Number of nets. */
388 SK_U32 NetsStarted; /* Number of nets started. */
389 SK_RLMT_NET Net[SK_MAX_NETS]; /* Array of available nets. */
390 SK_RLMT_PORT Port[SK_MAX_MACS]; /* Array of available ports. */
391
392/* ----- Private part ----- */
393 SK_BOOL CheckSwitch;
394 SK_BOOL RlmtOff; /* set to zero if the Mac addresses
395 are equal or the second one
396 is zero */
397 SK_U16 Align01;
398
399} SK_RLMT;
400
401
402extern SK_MAC_ADDR BridgeMcAddr;
403extern SK_MAC_ADDR SkRlmtMcAddr;
404
405/* function prototypes ********************************************************/
406
407
408#ifndef SK_KR_PROTO
409
410/* Functions provided by SkRlmt */
411
412/* ANSI/C++ compliant function prototypes */
413
414extern void SkRlmtInit(
415 SK_AC *pAC,
416 SK_IOC IoC,
417 int Level);
418
419extern int SkRlmtEvent(
420 SK_AC *pAC,
421 SK_IOC IoC,
422 SK_U32 Event,
423 SK_EVPARA Para);
424
425#else /* defined(SK_KR_PROTO) */
426
427/* Non-ANSI/C++ compliant function prototypes */
428
429#error KR-style function prototypes are not yet provided.
430
431#endif /* defined(SK_KR_PROTO)) */
432
433
434#ifdef __cplusplus
435}
436#endif /* __cplusplus */
437
438#endif /* __INC_SKRLMT_H */
diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
deleted file mode 100644
index 04e6d7c1ec33..000000000000
--- a/drivers/net/sk98lin/h/sktimer.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sktimer.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.11 $
6 * Date: $Date: 2003/09/16 12:58:18 $
7 * Purpose: Defines for the timer functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKTIMER.H contains all defines and types for the timer functions
27 */
28
29#ifndef _SKTIMER_H_
30#define _SKTIMER_H_
31
32#include "h/skqueue.h"
33
34/*
35 * SK timer
36 * - needed wherever a timer is used. Put this in your data structure
37 * wherever you want.
38 */
39typedef struct s_Timer SK_TIMER;
40
41struct s_Timer {
42 SK_TIMER *TmNext; /* linked list */
43 SK_U32 TmClass; /* Timer Event class */
44 SK_U32 TmEvent; /* Timer Event value */
45 SK_EVPARA TmPara; /* Timer Event parameter */
46 SK_U32 TmDelta; /* delta time */
47 int TmActive; /* flag: active/inactive */
48};
49
50/*
51 * Timer control struct.
52 * - use in Adapters context name pAC->Tim
53 */
54typedef struct s_TimCtrl {
55 SK_TIMER *StQueue; /* Head of Timer queue */
56} SK_TIMCTRL;
57
58extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
59extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
60extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
61 SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
62extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
63#endif /* _SKTIMER_H_ */
diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
deleted file mode 100644
index 40edc96e1055..000000000000
--- a/drivers/net/sk98lin/h/sktypes.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sktypes.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.2 $
6 * Date: $Date: 2003/10/07 08:16:51 $
7 * Purpose: Define data types for Linux
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * In this file, all data types that are needed by the common modules
30 * are mapped to Linux data types.
31 *
32 *
33 * Include File Hierarchy:
34 *
35 *
36 ******************************************************************************/
37
38#ifndef __INC_SKTYPES_H
39#define __INC_SKTYPES_H
40
41
42/* defines *******************************************************************/
43
44/*
45 * Data types with a specific size. 'I' = signed, 'U' = unsigned.
46 */
47#define SK_I8 s8
48#define SK_U8 u8
49#define SK_I16 s16
50#define SK_U16 u16
51#define SK_I32 s32
52#define SK_U32 u32
53#define SK_I64 s64
54#define SK_U64 u64
55
56#define SK_UPTR ulong /* casting pointer <-> integral */
57
58/*
59* Boolean type.
60*/
61#define SK_BOOL SK_U8
62#define SK_FALSE 0
63#define SK_TRUE (!SK_FALSE)
64
65/* typedefs *******************************************************************/
66
67/* function prototypes ********************************************************/
68
69#endif /* __INC_SKTYPES_H */
diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
deleted file mode 100644
index a1a7294828e5..000000000000
--- a/drivers/net/sk98lin/h/skversion.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/******************************************************************************
2 *
3 * Name: version.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.5 $
6 * Date: $Date: 2003/10/07 08:16:51 $
7 * Purpose: SK specific Error log support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifdef lint
26static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
27static const char SysKonnectBuildNumber[] =
28 "@(#)SK-BUILD: 6.23 PL: 01";
29#endif /* !defined(lint) */
30
31#define BOOT_STRING "sk98lin: Network Device Driver v6.23\n" \
32 "(C)Copyright 1999-2004 Marvell(R)."
33
34#define VER_STRING "6.23"
35#define DRIVER_FILE_NAME "sk98lin"
36#define DRIVER_REL_DATE "Feb-13-2004"
37
38
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
deleted file mode 100644
index fdd9e48e8040..000000000000
--- a/drivers/net/sk98lin/h/skvpd.h
+++ /dev/null
@@ -1,248 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skvpd.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.15 $
6 * Date: $Date: 2003/01/13 10:39:38 $
7 * Purpose: Defines and Macros for VPD handling
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/*
25 * skvpd.h contains Diagnostic specific defines for VPD handling
26 */
27
28#ifndef __INC_SKVPD_H_
29#define __INC_SKVPD_H_
30
31/*
32 * Define Resource Type Identifiers and VPD keywords
33 */
34#define RES_ID 0x82 /* Resource Type ID String (Product Name) */
35#define RES_VPD_R 0x90 /* start of VPD read only area */
36#define RES_VPD_W 0x91 /* start of VPD read/write area */
37#define RES_END 0x78 /* Resource Type End Tag */
38
39#ifndef VPD_NAME
40#define VPD_NAME "Name" /* Product Name, VPD name of RES_ID */
41#endif /* VPD_NAME */
42#define VPD_PN "PN" /* Adapter Part Number */
43#define VPD_EC "EC" /* Adapter Engineering Level */
44#define VPD_MN "MN" /* Manufacture ID */
45#define VPD_SN "SN" /* Serial Number */
46#define VPD_CP "CP" /* Extended Capability */
47#define VPD_RV "RV" /* Checksum and Reserved */
48#define VPD_YA "YA" /* Asset Tag Identifier */
49#define VPD_VL "VL" /* First Error Log Message (SK specific) */
50#define VPD_VF "VF" /* Second Error Log Message (SK specific) */
51#define VPD_RW "RW" /* Remaining Read / Write Area */
52
53/* 'type' values for vpd_setup_para() */
54#define VPD_RO_KEY 1 /* RO keys are "PN", "EC", "MN", "SN", "RV" */
55#define VPD_RW_KEY 2 /* RW keys are "Yx", "Vx", and "RW" */
56
57/* 'op' values for vpd_setup_para() */
58#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */
59#define OWR_KEY 2 /* overwrite key if already exists */
60
61/*
62 * Define READ and WRITE Constants.
63 */
64
65#define VPD_DEV_ID_GENESIS 0x4300
66
67#define VPD_SIZE_YUKON 256
68#define VPD_SIZE_GENESIS 512
69#define VPD_SIZE 512
70#define VPD_READ 0x0000
71#define VPD_WRITE 0x8000
72
73#define VPD_STOP(pAC,IoC) VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
74
75#define VPD_GET_RES_LEN(p) ((unsigned int) \
76 (* (SK_U8 *)&(p)[1]) |\
77 ((* (SK_U8 *)&(p)[2]) << 8))
78#define VPD_GET_VPD_LEN(p) ((unsigned int)(* (SK_U8 *)&(p)[2]))
79#define VPD_GET_VAL(p) ((char *)&(p)[3])
80
81#define VPD_MAX_LEN 50
82
83/* VPD status */
84 /* bit 7..1 reserved */
85#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */
86 /* and vpd_free_rw valid */
87
88/*
89 * VPD structs
90 */
91typedef struct s_vpd_status {
92 unsigned short Align01; /* Alignment */
93 unsigned short vpd_status; /* VPD status, description see above */
94 int vpd_free_ro; /* unused bytes in read only area */
95 int vpd_free_rw; /* bytes available in read/write area */
96} SK_VPD_STATUS;
97
98typedef struct s_vpd {
99 SK_VPD_STATUS v; /* VPD status structure */
100 char vpd_buf[VPD_SIZE]; /* VPD buffer */
101 int rom_size; /* VPD ROM Size from PCI_OUR_REG_2 */
102 int vpd_size; /* saved VPD-size */
103} SK_VPD;
104
105typedef struct s_vpd_para {
106 unsigned int p_len; /* parameter length */
107 char *p_val; /* points to the value */
108} SK_VPD_PARA;
109
110/*
111 * structure of Large Resource Type Identifiers
112 */
113
114/* was removed because of alignment problems */
115
116/*
117 * structure of VPD keywords
118 */
119typedef struct s_vpd_key {
120 char p_key[2]; /* 2 bytes ID string */
121 unsigned char p_len; /* 1 byte length */
122 char p_val; /* start of the value string */
123} SK_VPD_KEY;
124
125
126/*
127 * System specific VPD macros
128 */
129#ifndef SKDIAG
130#ifndef VPD_DO_IO
131#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val)
132#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val)
133#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal)
134#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal)
135#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal)
136#else /* VPD_DO_IO */
137#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val)
138#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val)
139#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal)
140#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal)
141#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
142#endif /* VPD_DO_IO */
143#else /* SKDIAG */
144#define VPD_OUT8(pAC,Ioc,Addr,Val) { \
145 if ((pAC)->DgT.DgUseCfgCycle) \
146 SkPciWriteCfgByte(pAC,Addr,Val); \
147 else \
148 SK_OUT8(pAC,PCI_C(Addr),Val); \
149 }
150#define VPD_OUT16(pAC,Ioc,Addr,Val) { \
151 if ((pAC)->DgT.DgUseCfgCycle) \
152 SkPciWriteCfgWord(pAC,Addr,Val); \
153 else \
154 SK_OUT16(pAC,PCI_C(Addr),Val); \
155 }
156#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
157 if ((pAC)->DgT.DgUseCfgCycle) \
158 SkPciReadCfgByte(pAC,Addr,pVal); \
159 else \
160 SK_IN8(pAC,PCI_C(Addr),pVal); \
161 }
162#define VPD_IN16(pAC,Ioc,Addr,pVal) { \
163 if ((pAC)->DgT.DgUseCfgCycle) \
164 SkPciReadCfgWord(pAC,Addr,pVal); \
165 else \
166 SK_IN16(pAC,PCI_C(Addr),pVal); \
167 }
168#define VPD_IN32(pAC,Ioc,Addr,pVal) { \
169 if ((pAC)->DgT.DgUseCfgCycle) \
170 SkPciReadCfgDWord(pAC,Addr,pVal); \
171 else \
172 SK_IN32(pAC,PCI_C(Addr),pVal); \
173 }
174#endif /* nSKDIAG */
175
176/* function prototypes ********************************************************/
177
178#ifndef SK_KR_PROTO
179#ifdef SKDIAG
180extern SK_U32 VpdReadDWord(
181 SK_AC *pAC,
182 SK_IOC IoC,
183 int addr);
184#endif /* SKDIAG */
185
186extern SK_VPD_STATUS *VpdStat(
187 SK_AC *pAC,
188 SK_IOC IoC);
189
190extern int VpdKeys(
191 SK_AC *pAC,
192 SK_IOC IoC,
193 char *buf,
194 int *len,
195 int *elements);
196
197extern int VpdRead(
198 SK_AC *pAC,
199 SK_IOC IoC,
200 const char *key,
201 char *buf,
202 int *len);
203
204extern SK_BOOL VpdMayWrite(
205 char *key);
206
207extern int VpdWrite(
208 SK_AC *pAC,
209 SK_IOC IoC,
210 const char *key,
211 const char *buf);
212
213extern int VpdDelete(
214 SK_AC *pAC,
215 SK_IOC IoC,
216 char *key);
217
218extern int VpdUpdate(
219 SK_AC *pAC,
220 SK_IOC IoC);
221
222#ifdef SKDIAG
223extern int VpdReadBlock(
224 SK_AC *pAC,
225 SK_IOC IoC,
226 char *buf,
227 int addr,
228 int len);
229
230extern int VpdWriteBlock(
231 SK_AC *pAC,
232 SK_IOC IoC,
233 char *buf,
234 int addr,
235 int len);
236#endif /* SKDIAG */
237#else /* SK_KR_PROTO */
238extern SK_U32 VpdReadDWord();
239extern SK_VPD_STATUS *VpdStat();
240extern int VpdKeys();
241extern int VpdRead();
242extern SK_BOOL VpdMayWrite();
243extern int VpdWrite();
244extern int VpdDelete();
245extern int VpdUpdate();
246#endif /* SK_KR_PROTO */
247
248#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
deleted file mode 100644
index 7f8e6d0084c7..000000000000
--- a/drivers/net/sk98lin/h/xmac_ii.h
+++ /dev/null
@@ -1,1579 +0,0 @@
1/******************************************************************************
2 *
3 * Name: xmac_ii.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.52 $
6 * Date: $Date: 2003/10/02 16:35:50 $
7 * Purpose: Defines and Macros for Gigabit Ethernet Controller
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_XMAC_H
26#define __INC_XMAC_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34/*
35 * XMAC II registers
36 *
37 * The XMAC registers are 16 or 32 bits wide.
38 * The XMACs host processor interface is set to 16 bit mode,
39 * therefore ALL registers will be addressed with 16 bit accesses.
40 *
41 * The following macros are provided to access the XMAC registers
42 * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
43 * XM_INHASH(), and XM_OUTHASH().
44 * The macros are defined in SkGeHw.h.
45 *
46 * Note: NA reg = Network Address e.g DA, SA etc.
47 *
48 */
49#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */
50 /* 0x0004: reserved */
51#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */
52#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/
53#define XM_1L_VLAN_TAG 0x0010 /* 16 bit r/w One Level VLAN Tag ID */
54#define XM_2L_VLAN_TAG 0x0014 /* 16 bit r/w Two Level VLAN Tag ID */
55 /* 0x0018 - 0x001e: reserved */
56#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */
57#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */
58#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */
59#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */
60#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */
61#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */
62#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */
63 /* 0x003c: reserved */
64#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */
65#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */
66#define XM_ISRC 0x0048 /* 16 bit r/o Interrupt Status Register */
67#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */
68 /* 0x0050 - 0x005e: reserved */
69#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */
70#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */
71#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */
72#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */
73#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */
74 /* 0x006e: reserved */
75#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */
76#define XM_MAC_OPCODE 0x0074 /* 16 bit r/w Opcode for MAC control frames */
77#define XM_MAC_PTIME 0x0076 /* 16 bit r/w Pause time for MAC ctrl frames*/
78#define XM_TX_STAT 0x0078 /* 32 bit r/o Tx Status LIFO Register */
79
80 /* 0x0080 - 0x00fc: 16 NA reg r/w Exact Match Address Registers */
81 /* use the XM_EXM() macro to address */
82#define XM_EXM_START 0x0080 /* r/w Start Address of the EXM Regs */
83
84 /*
85 * XM_EXM(Reg)
86 *
87 * returns the XMAC address offset of specified Exact Match Addr Reg
88 *
89 * para: Reg EXM register to addr (0 .. 15)
90 *
91 * usage: XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
92 */
93#define XM_EXM(Reg) (XM_EXM_START + ((Reg) << 3))
94
95#define XM_SRC_CHK 0x0100 /* NA reg r/w Source Check Address Register */
96#define XM_SA 0x0108 /* NA reg r/w Station Address Register */
97#define XM_HSM 0x0110 /* 64 bit r/w Hash Match Address Registers */
98#define XM_RX_LO_WM 0x0118 /* 16 bit r/w Receive Low Water Mark */
99#define XM_RX_HI_WM 0x011a /* 16 bit r/w Receive High Water Mark */
100#define XM_RX_THR 0x011c /* 32 bit r/w Receive Request Threshold */
101#define XM_DEV_ID 0x0120 /* 32 bit r/o Device ID Register */
102#define XM_MODE 0x0124 /* 32 bit r/w Mode Register */
103#define XM_LSA 0x0128 /* NA reg r/o Last Source Register */
104 /* 0x012e: reserved */
105#define XM_TS_READ 0x0130 /* 32 bit r/o Time Stamp Read Register */
106#define XM_TS_LOAD 0x0134 /* 32 bit r/o Time Stamp Load Value */
107 /* 0x0138 - 0x01fe: reserved */
108#define XM_STAT_CMD 0x0200 /* 16 bit r/w Statistics Command Register */
109#define XM_RX_CNT_EV 0x0204 /* 32 bit r/o Rx Counter Event Register */
110#define XM_TX_CNT_EV 0x0208 /* 32 bit r/o Tx Counter Event Register */
111#define XM_RX_EV_MSK 0x020c /* 32 bit r/w Rx Counter Event Mask */
112#define XM_TX_EV_MSK 0x0210 /* 32 bit r/w Tx Counter Event Mask */
113 /* 0x0204 - 0x027e: reserved */
114#define XM_TXF_OK 0x0280 /* 32 bit r/o Frames Transmitted OK Conuter */
115#define XM_TXO_OK_HI 0x0284 /* 32 bit r/o Octets Transmitted OK High Cnt*/
116#define XM_TXO_OK_LO 0x0288 /* 32 bit r/o Octets Transmitted OK Low Cnt */
117#define XM_TXF_BC_OK 0x028c /* 32 bit r/o Broadcast Frames Xmitted OK */
118#define XM_TXF_MC_OK 0x0290 /* 32 bit r/o Multicast Frames Xmitted OK */
119#define XM_TXF_UC_OK 0x0294 /* 32 bit r/o Unicast Frames Xmitted OK */
120#define XM_TXF_LONG 0x0298 /* 32 bit r/o Tx Long Frame Counter */
121#define XM_TXE_BURST 0x029c /* 32 bit r/o Tx Burst Event Counter */
122#define XM_TXF_MPAUSE 0x02a0 /* 32 bit r/o Tx Pause MAC Ctrl Frame Cnt */
123#define XM_TXF_MCTRL 0x02a4 /* 32 bit r/o Tx MAC Ctrl Frame Counter */
124#define XM_TXF_SNG_COL 0x02a8 /* 32 bit r/o Tx Single Collision Counter */
125#define XM_TXF_MUL_COL 0x02ac /* 32 bit r/o Tx Multiple Collision Counter */
126#define XM_TXF_ABO_COL 0x02b0 /* 32 bit r/o Tx aborted due to Exces. Col. */
127#define XM_TXF_LAT_COL 0x02b4 /* 32 bit r/o Tx Late Collision Counter */
128#define XM_TXF_DEF 0x02b8 /* 32 bit r/o Tx Deferred Frame Counter */
129#define XM_TXF_EX_DEF 0x02bc /* 32 bit r/o Tx Excessive Deferall Counter */
130#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit r/o Tx FIFO Underrun Event Cnt */
131#define XM_TXE_CS_ERR 0x02c4 /* 32 bit r/o Tx Carrier Sense Error Cnt */
132#define XM_TXP_UTIL 0x02c8 /* 32 bit r/o Tx Utilization in % */
133 /* 0x02cc - 0x02ce: reserved */
134#define XM_TXF_64B 0x02d0 /* 32 bit r/o 64 Byte Tx Frame Counter */
135#define XM_TXF_127B 0x02d4 /* 32 bit r/o 65-127 Byte Tx Frame Counter */
136#define XM_TXF_255B 0x02d8 /* 32 bit r/o 128-255 Byte Tx Frame Counter */
137#define XM_TXF_511B 0x02dc /* 32 bit r/o 256-511 Byte Tx Frame Counter */
138#define XM_TXF_1023B 0x02e0 /* 32 bit r/o 512-1023 Byte Tx Frame Counter*/
139#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit r/o 1024-MaxSize Byte Tx Frame Cnt*/
140 /* 0x02e8 - 0x02fe: reserved */
141#define XM_RXF_OK 0x0300 /* 32 bit r/o Frames Received OK */
142#define XM_RXO_OK_HI 0x0304 /* 32 bit r/o Octets Received OK High Cnt */
143#define XM_RXO_OK_LO 0x0308 /* 32 bit r/o Octets Received OK Low Counter*/
144#define XM_RXF_BC_OK 0x030c /* 32 bit r/o Broadcast Frames Received OK */
145#define XM_RXF_MC_OK 0x0310 /* 32 bit r/o Multicast Frames Received OK */
146#define XM_RXF_UC_OK 0x0314 /* 32 bit r/o Unicast Frames Received OK */
147#define XM_RXF_MPAUSE 0x0318 /* 32 bit r/o Rx Pause MAC Ctrl Frame Cnt */
148#define XM_RXF_MCTRL 0x031c /* 32 bit r/o Rx MAC Ctrl Frame Counter */
149#define XM_RXF_INV_MP 0x0320 /* 32 bit r/o Rx invalid Pause Frame Cnt */
150#define XM_RXF_INV_MOC 0x0324 /* 32 bit r/o Rx Frames with inv. MAC Opcode*/
151#define XM_RXE_BURST 0x0328 /* 32 bit r/o Rx Burst Event Counter */
152#define XM_RXE_FMISS 0x032c /* 32 bit r/o Rx Missed Frames Event Cnt */
153#define XM_RXF_FRA_ERR 0x0330 /* 32 bit r/o Rx Framing Error Counter */
154#define XM_RXE_FIFO_OV 0x0334 /* 32 bit r/o Rx FIFO overflow Event Cnt */
155#define XM_RXF_JAB_PKT 0x0338 /* 32 bit r/o Rx Jabber Packet Frame Cnt */
156#define XM_RXE_CAR_ERR 0x033c /* 32 bit r/o Rx Carrier Event Error Cnt */
157#define XM_RXF_LEN_ERR 0x0340 /* 32 bit r/o Rx in Range Length Error */
158#define XM_RXE_SYM_ERR 0x0344 /* 32 bit r/o Rx Symbol Error Counter */
159#define XM_RXE_SHT_ERR 0x0348 /* 32 bit r/o Rx Short Event Error Cnt */
160#define XM_RXE_RUNT 0x034c /* 32 bit r/o Rx Runt Event Counter */
161#define XM_RXF_LNG_ERR 0x0350 /* 32 bit r/o Rx Frame too Long Error Cnt */
162#define XM_RXF_FCS_ERR 0x0354 /* 32 bit r/o Rx Frame Check Seq. Error Cnt */
163 /* 0x0358 - 0x035a: reserved */
164#define XM_RXF_CEX_ERR 0x035c /* 32 bit r/o Rx Carrier Ext Error Frame Cnt*/
165#define XM_RXP_UTIL 0x0360 /* 32 bit r/o Rx Utilization in % */
166 /* 0x0364 - 0x0366: reserved */
167#define XM_RXF_64B 0x0368 /* 32 bit r/o 64 Byte Rx Frame Counter */
168#define XM_RXF_127B 0x036c /* 32 bit r/o 65-127 Byte Rx Frame Counter */
169#define XM_RXF_255B 0x0370 /* 32 bit r/o 128-255 Byte Rx Frame Counter */
170#define XM_RXF_511B 0x0374 /* 32 bit r/o 256-511 Byte Rx Frame Counter */
171#define XM_RXF_1023B 0x0378 /* 32 bit r/o 512-1023 Byte Rx Frame Counter*/
172#define XM_RXF_MAX_SZ 0x037c /* 32 bit r/o 1024-MaxSize Byte Rx Frame Cnt*/
173 /* 0x02e8 - 0x02fe: reserved */
174
175
176/*----------------------------------------------------------------------------*/
177/*
178 * XMAC Bit Definitions
179 *
180 * If the bit access behaviour differs from the register access behaviour
181 * (r/w, r/o) this is documented after the bit number.
182 * The following bit access behaviours are used:
183 * (sc) self clearing
184 * (ro) read only
185 */
186
187/* XM_MMU_CMD 16 bit r/w MMU Command Register */
188 /* Bit 15..13: reserved */
189#define XM_MMU_PHY_RDY (1<<12) /* Bit 12: PHY Read Ready */
190#define XM_MMU_PHY_BUSY (1<<11) /* Bit 11: PHY Busy */
191#define XM_MMU_IGN_PF (1<<10) /* Bit 10: Ignore Pause Frame */
192#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */
193 /* Bit 8: reserved */
194#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */
195#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */
196#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */
197#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */
198#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */
199#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Loopback Mode */
200#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */
201#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */
202
203
204/* XM_TX_CMD 16 bit r/w Transmit Command Register */
205 /* Bit 15..7: reserved */
206#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (Tx Bk2Bk)*/
207#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */
208#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */
209#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */
210#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */
211#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */
212#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */
213
214
215/* XM_TX_RT_LIM 16 bit r/w Transmit Retry Limit Register */
216 /* Bit 15..5: reserved */
217#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */
218
219
220/* XM_TX_STIME 16 bit r/w Transmit Slottime Register */
221 /* Bit 15..7: reserved */
222#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */
223
224
225/* XM_TX_IPG 16 bit r/w Transmit Inter Packet Gap */
226 /* Bit 15..8: reserved */
227#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */
228
229
230/* XM_RX_CMD 16 bit r/w Receive Command Register */
231 /* Bit 15..9: reserved */
232#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */
233 /* inrange error packets */
234#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */
235 /* jumbo packets */
236#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */
237#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */
238#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */
239#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */
240#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */
241#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of Rx frames */
242#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */
243
244
245/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
246 /* Bit 15..5: reserved */
247#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */
248
249
250/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
251 /* Bit 31..7: reserved */
252#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto-Neg. in progress */
253#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */
254 /* Bit 4: reserved */
255#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */
256#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */
257 /* Bit 1: reserved */
258#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */
259
260
261/* XM_IMSK 16 bit r/w Interrupt Mask Register */
262/* XM_ISRC 16 bit r/o Interrupt Status Register */
263 /* Bit 15: reserved */
264#define XM_IS_LNK_AE (1<<14) /* Bit 14: Link Asynchronous Event */
265#define XM_IS_TX_ABORT (1<<13) /* Bit 13: Transmit Abort, late Col. etc */
266#define XM_IS_FRC_INT (1<<12) /* Bit 12: Force INT bit set in GP */
267#define XM_IS_INP_ASS (1<<11) /* Bit 11: Input Asserted, GP bit 0 set */
268#define XM_IS_LIPA_RC (1<<10) /* Bit 10: Link Partner requests config */
269#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */
270#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */
271#define XM_IS_AND (1<<7) /* Bit 7: Auto-Negotiation Done */
272#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */
273#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */
274#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */
275#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */
276#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */
277#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */
278#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */
279
280#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
281 XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
282
283
284/* XM_HW_CFG 16 bit r/w Hardware Config Register */
285 /* Bit 15.. 4: reserved */
286#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */
287#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/
288 /* Bit 1: reserved */
289#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */
290
291
292/* XM_TX_LO_WM 16 bit r/w Tx FIFO Low Water Mark */
293/* XM_TX_HI_WM 16 bit r/w Tx FIFO High Water Mark */
294 /* Bit 15..10 reserved */
295#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */
296
297/* XM_TX_THR 16 bit r/w Tx Request Threshold */
298/* XM_HT_THR 16 bit r/w Host Request Threshold */
299/* XM_RX_THR 16 bit r/w Rx Request Threshold */
300 /* Bit 15..11 reserved */
301#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Rx/Tx Request Threshold bits */
302
303
304/* XM_TX_STAT 32 bit r/o Tx Status LIFO Register */
305#define XM_ST_VALID (1UL<<31) /* Bit 31: Status Valid */
306#define XM_ST_BYTE_CNT (0x3fffL<<17) /* Bit 30..17: Tx frame Length */
307#define XM_ST_RETRY_CNT (0x1fL<<12) /* Bit 16..12: Retry Count */
308#define XM_ST_EX_COL (1L<<11) /* Bit 11: Excessive Collisions */
309#define XM_ST_EX_DEF (1L<<10) /* Bit 10: Excessive Deferral */
310#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/
311#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */
312#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */
313#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */
314#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */
315#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */
316#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */
317#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */
318#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */
319#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */
320
321/* XM_RX_LO_WM 16 bit r/w Receive Low Water Mark */
322/* XM_RX_HI_WM 16 bit r/w Receive High Water Mark */
323 /* Bit 15..11: reserved */
324#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */
325
326
327/* XM_DEV_ID 32 bit r/o Device ID Register */
328#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */
329#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */
330
331
332/* XM_MODE 32 bit r/w Mode Register */
333 /* Bit 31..27: reserved */
334#define XM_MD_ENA_REJ (1L<<26) /* Bit 26: Enable Frame Reject */
335#define XM_MD_SPOE_E (1L<<25) /* Bit 25: Send Pause on Edge */
336 /* extern generated */
337#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode */
338#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFO full */
339 /* intern generated */
340#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Little Endian */
341#define XM_MD_TX_CONT (1L<<21) /* Bit 21: Send Continuous */
342#define XM_MD_TX_PAUSE (1L<<20) /* Bit 20: (sc) Send Pause Frame */
343#define XM_MD_ATS (1L<<19) /* Bit 19: Append Time Stamp */
344#define XM_MD_SPOL_I (1L<<18) /* Bit 18: Send Pause on Low */
345 /* intern generated */
346#define XM_MD_SPOH_I (1L<<17) /* Bit 17: Send Pause on High */
347 /* intern generated */
348#define XM_MD_CAP (1L<<16) /* Bit 16: Check Address Pair */
349#define XM_MD_ENA_HASH (1L<<15) /* Bit 15: Enable Hashing */
350#define XM_MD_CSA (1L<<14) /* Bit 14: Check Station Address */
351#define XM_MD_CAA (1L<<13) /* Bit 13: Check Address Array */
352#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frame */
353#define XM_MD_RX_RUNT (1L<<11) /* Bit 11: Rx Runt Frames */
354#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err Frame */
355#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frame */
356#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frame */
357#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frame */
358#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */
359#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */
360#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Broadcast */
361#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */
362#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */
363#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */
364#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */
365
366#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
367#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
368 XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
369
370/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
371 /* Bit 16..6: reserved */
372#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */
373#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */
374#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */
375#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */
376#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */
377#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */
378
379
380/* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */
381/* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */
382#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/
383#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/
384#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/
385#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/
386#define XMR_127B_OV (1L<<27) /* Bit 27: 65-127 Byte Rx Cnt Ov */
387#define XMR_64B_OV (1L<<26) /* Bit 26: 64 Byte Rx Cnt Ov */
388#define XMR_UTIL_OV (1L<<25) /* Bit 25: Rx Util Cnt Overflow */
389#define XMR_UTIL_UR (1L<<24) /* Bit 24: Rx Util Cnt Underrun */
390#define XMR_CEX_ERR_OV (1L<<23) /* Bit 23: CEXT Err Cnt Ov */
391 /* Bit 22: reserved */
392#define XMR_FCS_ERR_OV (1L<<21) /* Bit 21: Rx FCS Error Cnt Ov */
393#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov*/
394#define XMR_RUNT_OV (1L<<19) /* Bit 19: Runt Event Cnt Ov */
395#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov*/
396#define XMR_SYM_ERR_OV (1L<<17) /* Bit 17: Rx Sym Err Cnt Ov */
397 /* Bit 16: reserved */
398#define XMR_CAR_ERR_OV (1L<<15) /* Bit 15: Rx Carr Ev Err Cnt Ov */
399#define XMR_JAB_PKT_OV (1L<<14) /* Bit 14: Rx Jabb Packet Cnt Ov */
400#define XMR_FIFO_OV (1L<<13) /* Bit 13: Rx FIFO Ov Ev Cnt Ov */
401#define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */
402#define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */
403#define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */
404#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/
405#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */
406#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */
407#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/
408#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/
409#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */
410#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */
411#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/
412#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/
413#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */
414
415#define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV)
416
417/* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */
418/* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */
419 /* Bit 31..26: reserved */
420#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/
421#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov*/
422#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov*/
423#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov*/
424#define XMT_127B_OV (1L<<21) /* Bit 21: 65-127 Byte Tx Cnt Ov */
425#define XMT_64B_OV (1L<<20) /* Bit 20: 64 Byte Tx Cnt Ov */
426#define XMT_UTIL_OV (1L<<19) /* Bit 19: Tx Util Cnt Overflow */
427#define XMT_UTIL_UR (1L<<18) /* Bit 18: Tx Util Cnt Underrun */
428#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov*/
429#define XMT_FIFO_UR_OV (1L<<16) /* Bit 16: Tx FIFO Ur Ev Cnt Ov */
430#define XMT_EX_DEF_OV (1L<<15) /* Bit 15: Tx Ex Deferall Cnt Ov */
431#define XMT_DEF (1L<<14) /* Bit 14: Tx Deferred Cnt Ov */
432#define XMT_LAT_COL_OV (1L<<13) /* Bit 13: Tx Late Col Cnt Ov */
433#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/
434#define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */
435#define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */
436#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/
437#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/
438#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */
439#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */
440#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */
441#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */
442#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */
443#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/
444#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/
445#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */
446
447#define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV)
448
449/*
450 * Receive Frame Status Encoding
451 */
452#define XMR_FS_LEN (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */
453#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: tagged wh 2Lev VLAN ID*/
454#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: tagged wh 1Lev VLAN ID*/
455#define XMR_FS_BC (1L<<15) /* Bit 15: Broadcast Frame */
456#define XMR_FS_MC (1L<<14) /* Bit 14: Multicast Frame */
457#define XMR_FS_UC (1L<<13) /* Bit 13: Unicast Frame */
458 /* Bit 12: reserved */
459#define XMR_FS_BURST (1L<<11) /* Bit 11: Burst Mode */
460#define XMR_FS_CEX_ERR (1L<<10) /* Bit 10: Carrier Ext. Error */
461#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */
462#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */
463#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */
464#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */
465#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */
466#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Frame */
467#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Giant (Jumbo) Frame */
468#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */
469#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */
470#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */
471
472/*
473 * XMR_FS_ERR will be set if
474 * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
475 * XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
476 * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
477 * XMR_FS_ERR unless the corresponding bit in the Receive Command
478 * Register is set.
479 */
480#define XMR_FS_ANY_ERR XMR_FS_ERR
481
482/*----------------------------------------------------------------------------*/
483/*
484 * XMAC-PHY Registers, indirect addressed over the XMAC
485 */
486#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */
487#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */
488#define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
489#define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
490#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
491#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */
492#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
493#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */
494#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
495 /* 0x09 - 0x0e: reserved */
496#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */
497#define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */
498
499/*----------------------------------------------------------------------------*/
500/*
501 * Broadcom-PHY Registers, indirect addressed over XMAC
502 */
503#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */
504#define PHY_BCOM_STAT 0x01 /* 16 bit r/o PHY Status Register */
505#define PHY_BCOM_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
506#define PHY_BCOM_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
507#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
508#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
509#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
510#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */
511#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
512 /* Broadcom-specific registers */
513#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
514#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
515 /* 0x0b - 0x0e: reserved */
516#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
517#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */
518#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */
519#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */
520#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */
521#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */
522 /* 0x15 - 0x17: reserved */
523#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */
524#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit r/o Auxiliary Stat Summary */
525#define PHY_BCOM_INT_STAT 0x1a /* 16 bit r/o Interrupt Status Reg */
526#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */
527 /* 0x1c: reserved */
528 /* 0x1d - 0x1f: test registers */
529
530/*----------------------------------------------------------------------------*/
531/*
532 * Marvel-PHY Registers, indirect addressed over GMAC
533 */
534#define PHY_MARV_CTRL 0x00 /* 16 bit r/w PHY Control Register */
535#define PHY_MARV_STAT 0x01 /* 16 bit r/o PHY Status Register */
536#define PHY_MARV_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
537#define PHY_MARV_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
538#define PHY_MARV_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
539#define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
540#define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
541#define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */
542#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
543 /* Marvel-specific registers */
544#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
545#define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
546 /* 0x0b - 0x0e: reserved */
547#define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
548#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */
549#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */
550#define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */
551#define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
552#define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */
553#define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */
554#define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */
555 /* 0x17: reserved */
556#define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */
557#define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */
558#define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */
559#define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */
560#define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */
561 /* 0x1d - 0x1f: reserved */
562
563/*----------------------------------------------------------------------------*/
564/*
565 * Level One-PHY Registers, indirect addressed over XMAC
566 */
567#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */
568#define PHY_LONE_STAT 0x01 /* 16 bit r/o PHY Status Register */
569#define PHY_LONE_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
570#define PHY_LONE_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
571#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
572#define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
573#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
574#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */
575#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
576 /* Level One-specific registers */
577#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/
578#define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
579 /* 0x0b -0x0e: reserved */
580#define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
581#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/
582#define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */
583#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */
584#define PHY_LONE_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
585#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */
586#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */
587#define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */
588 /* 0x17 -0x1c: reserved */
589
590/*----------------------------------------------------------------------------*/
591/*
592 * National-PHY Registers, indirect addressed over XMAC
593 */
594#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */
595#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */
596#define PHY_NAT_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
597#define PHY_NAT_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
598#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
599#define PHY_NAT_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */
600#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
601#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */
602#define PHY_NAT_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner Reg */
603 /* National-specific registers */
604#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */
605#define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
606 /* 0x0b -0x0e: reserved */
607#define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */
608#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */
609#define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */
610#define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */
611#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */
612#define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */
613 /* 0x15 -0x18: reserved */
614#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */
615
616
617/*----------------------------------------------------------------------------*/
618
619/*
620 * PHY bit definitions
621 * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
622 * XMAC/Broadcom/LevelOne/National/Marvell-specific.
623 * All other are general.
624 */
625
626/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/
627/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/
628/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/
629/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/
630#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */
631#define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */
632#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
633#define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */
634#define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
635#define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
636#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */
637#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */
638#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */
639#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */
640 /* Bit 5..0: reserved */
641
642#define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */
643#define PHY_CT_SP100 PHY_CT_SPS_LSB /* enable speed of 100 Mbps */
644#define PHY_CT_SP10 (0) /* enable speed of 10 Mbps */
645
646
647/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/
648/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/
649/***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/
650/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/
651 /* Bit 15..9: reserved */
652 /* (BC/L1) 100/10 Mbps cap bits ignored*/
653#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */
654 /* Bit 7: reserved */
655#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */
656#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */
657#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */
658#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */
659#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */
660#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */
661#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */
662
663
664/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */
665/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */
666/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */
667/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */
668#define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */
669#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */
670#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */
671
672/* different Broadcom PHY Ids */
673#define PHY_BCOM_ID1_A1 0x6041
674#define PHY_BCOM_ID1_B2 0x6043
675#define PHY_BCOM_ID1_C0 0x6044
676#define PHY_BCOM_ID1_C5 0x6047
677
678
679/***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
680/***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
681#define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */
682#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */
683#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */
684 /* Bit 11.. 9: reserved */
685#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */
686#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */
687#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */
688 /* Bit 4.. 0: reserved */
689
690/***** PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
691/***** PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
692/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
693 /* Bit 14: reserved */
694#define PHY_B_AN_RF (1<<13) /* Bit 13: Remote Fault */
695 /* Bit 12: reserved */
696#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
697#define PHY_B_AN_PC (1<<10) /* Bit 10: Pause Capable */
698 /* Bit 9..5: 100/10 BT cap bits ingnored */
699#define PHY_B_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
700
701/***** PHY_LONE_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
702/***** PHY_LONE_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
703/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
704 /* Bit 14: reserved */
705#define PHY_L_AN_RF (1<<13) /* Bit 13: Remote Fault */
706 /* Bit 12: reserved */
707#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
708#define PHY_L_AN_PC (1<<10) /* Bit 10: Pause Capable */
709 /* Bit 9..5: 100/10 BT cap bits ingnored */
710#define PHY_L_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
711
712/***** PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
713/***** PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
714/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
715 /* Bit 14: reserved */
716#define PHY_N_AN_RF (1<<13) /* Bit 13: Remote Fault */
717 /* Bit 12: reserved */
718#define PHY_N_AN_100F (1<<11) /* Bit 11: 100Base-T2 FD Support */
719#define PHY_N_AN_100H (1<<10) /* Bit 10: 100Base-T2 HD Support */
720 /* Bit 9..5: 100/10 BT cap bits ingnored */
721#define PHY_N_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
722
723/* field type definition for PHY_x_AN_SEL */
724#define PHY_SEL_TYPE 0x01 /* 00001 = Ethernet */
725
726/***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
727 /* Bit 15..4: reserved */
728#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */
729#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */
730#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */
731 /* Bit 0: reserved */
732
733/***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
734/***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
735/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
736 /* Bit 15..5: reserved */
737#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */
738/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */
739/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */
740/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */
741#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */
742
743/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/
744/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/
745/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/
746/***** PHY_XMAC_NEPG_LP 16 bit r/o Next Page Link Partner *****/
747/***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/
748/***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/
749#define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */
750#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */
751#define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */
752#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack2, comply with msg content */
753#define PHY_NP_TOG (1<<11) /* Bit 11: Toggle Bit, ensure sync */
754#define PHY_NP_MSG 0x07ff /* Bit 10..0: Message from/to Link Partner */
755
756/*
757 * XMAC-Specific
758 */
759/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
760#define PHY_X_EX_FD (1<<15) /* Bit 15: Device Supports Full Duplex */
761#define PHY_X_EX_HD (1<<14) /* Bit 14: Device Supports Half Duplex */
762 /* Bit 13..0: reserved */
763
764/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
765 /* Bit 15..9: reserved */
766#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */
767#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */
768#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */
769#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */
770#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */
771 /* Bit 2..0: reserved */
772/*
773 * Remote Fault Bits (PHY_X_AN_RFB) encoding
774 */
775#define X_RFB_OK (0<<12) /* Bit 13..12 No errors, Link OK */
776#define X_RFB_LF (1<<12) /* Bit 13..12 Link Failure */
777#define X_RFB_OFF (2<<12) /* Bit 13..12 Offline */
778#define X_RFB_AN_ERR (3<<12) /* Bit 13..12 Auto-Negotiation Error */
779
780/*
781 * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
782 */
783#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */
784#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */
785#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */
786#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */
787
788
789/*
790 * Broadcom-Specific
791 */
792/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
793#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
794#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
795#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
796#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
797#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
798#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
799 /* Bit 7..0: reserved */
800
801/***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
802/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
803#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
804#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
805#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
806#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
807#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
808#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
809 /* Bit 9..8: reserved */
810#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
811
812/***** PHY_BCOM_EXT_STAT 16 bit r/o Extended Status Register *****/
813#define PHY_B_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
814#define PHY_B_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
815#define PHY_B_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
816#define PHY_B_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
817 /* Bit 11..0: reserved */
818
819/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/
820#define PHY_B_PEC_MAC_PHY (1<<15) /* Bit 15: 10BIT/GMI-Interface */
821#define PHY_B_PEC_DIS_CROSS (1<<14) /* Bit 14: Disable MDI Crossover */
822#define PHY_B_PEC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
823#define PHY_B_PEC_INT_DIS (1<<12) /* Bit 12: Interrupts Disabled */
824#define PHY_B_PEC_F_INT (1<<11) /* Bit 11: Force Interrupt */
825#define PHY_B_PEC_BY_45 (1<<10) /* Bit 10: Bypass 4B5B-Decoder */
826#define PHY_B_PEC_BY_SCR (1<<9) /* Bit 9: Bypass Scrambler */
827#define PHY_B_PEC_BY_MLT3 (1<<8) /* Bit 8: Bypass MLT3 Encoder */
828#define PHY_B_PEC_BY_RXA (1<<7) /* Bit 7: Bypass Rx Alignm. */
829#define PHY_B_PEC_RES_SCR (1<<6) /* Bit 6: Reset Scrambler */
830#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Ena LED Traffic Mode */
831#define PHY_B_PEC_LED_ON (1<<4) /* Bit 4: Force LED's on */
832#define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */
833#define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */
834#define PHY_B_PEC_3_LED (1<<1) /* Bit 1: Three Link LED mode */
835#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII FIFO Elasticy */
836
837/***** PHY_BCOM_P_EXT_STAT 16 bit r/o PHY Extended Status Reg *****/
838 /* Bit 15..14: reserved */
839#define PHY_B_PES_CROSS_STAT (1<<13) /* Bit 13: MDI Crossover Status */
840#define PHY_B_PES_INT_STAT (1<<12) /* Bit 12: Interrupt Status */
841#define PHY_B_PES_RRS (1<<11) /* Bit 11: Remote Receiver Stat. */
842#define PHY_B_PES_LRS (1<<10) /* Bit 10: Local Receiver Stat. */
843#define PHY_B_PES_LOCKED (1<<9) /* Bit 9: Locked */
844#define PHY_B_PES_LS (1<<8) /* Bit 8: Link Status */
845#define PHY_B_PES_RF (1<<7) /* Bit 7: Remote Fault */
846#define PHY_B_PES_CE_ER (1<<6) /* Bit 6: Carrier Ext Error */
847#define PHY_B_PES_BAD_SSD (1<<5) /* Bit 5: Bad SSD */
848#define PHY_B_PES_BAD_ESD (1<<4) /* Bit 4: Bad ESD */
849#define PHY_B_PES_RX_ER (1<<3) /* Bit 3: Receive Error */
850#define PHY_B_PES_TX_ER (1<<2) /* Bit 2: Transmit Error */
851#define PHY_B_PES_LOCK_ER (1<<1) /* Bit 1: Lock Error */
852#define PHY_B_PES_MLT3_ER (1<<0) /* Bit 0: MLT3 code Error */
853
854/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
855 /* Bit 15..8: reserved */
856#define PHY_B_FC_CTR 0xff /* Bit 7..0: False Carrier Counter */
857
858/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/
859#define PHY_B_RC_LOC_MSK 0xff00 /* Bit 15..8: Local Rx NOT_OK cnt */
860#define PHY_B_RC_REM_MSK 0x00ff /* Bit 7..0: Remote Rx NOT_OK cnt */
861
862/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/
863#define PHY_B_AC_L_SQE (1<<15) /* Bit 15: Low Squelch */
864#define PHY_B_AC_LONG_PACK (1<<14) /* Bit 14: Rx Long Packets */
865#define PHY_B_AC_ER_CTRL (3<<12) /* Bit 13..12: Edgerate Control */
866 /* Bit 11: reserved */
867#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: Tx test bit, always 1 */
868 /* Bit 9.. 8: reserved */
869#define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */
870 /* Bit 6: reserved */
871#define PHY_B_AC_DIS_PM (1<<5) /* Bit 5: dis power management */
872 /* Bit 4: reserved */
873#define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */
874 /* Bit 2.. 0: reserved */
875
876/***** PHY_BCOM_AUX_STAT 16 bit r/o Auxiliary Status Reg *****/
877#define PHY_B_AS_AN_C (1<<15) /* Bit 15: AutoNeg complete */
878#define PHY_B_AS_AN_CA (1<<14) /* Bit 14: AN Complete Ack */
879#define PHY_B_AS_ANACK_D (1<<13) /* Bit 13: AN Ack Detect */
880#define PHY_B_AS_ANAB_D (1<<12) /* Bit 12: AN Ability Detect */
881#define PHY_B_AS_NPW (1<<11) /* Bit 11: AN Next Page Wait */
882#define PHY_B_AS_AN_RES_MSK (7<<8) /* Bit 10..8: AN HDC */
883#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault */
884#define PHY_B_AS_RF (1<<6) /* Bit 6: Remote Fault */
885#define PHY_B_AS_ANP_R (1<<5) /* Bit 5: AN Page Received */
886#define PHY_B_AS_LP_ANAB (1<<4) /* Bit 4: LP AN Ability */
887#define PHY_B_AS_LP_NPAB (1<<3) /* Bit 3: LP Next Page Ability */
888#define PHY_B_AS_LS (1<<2) /* Bit 2: Link Status */
889#define PHY_B_AS_PRR (1<<1) /* Bit 1: Pause Resolution-Rx */
890#define PHY_B_AS_PRT (1<<0) /* Bit 0: Pause Resolution-Tx */
891
892#define PHY_B_AS_PAUSE_MSK (PHY_B_AS_PRR | PHY_B_AS_PRT)
893
894/***** PHY_BCOM_INT_STAT 16 bit r/o Interrupt Status Reg *****/
895/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
896 /* Bit 15: reserved */
897#define PHY_B_IS_PSE (1<<14) /* Bit 14: Pair Swap Error */
898#define PHY_B_IS_MDXI_SC (1<<13) /* Bit 13: MDIX Status Change */
899#define PHY_B_IS_HCT (1<<12) /* Bit 12: counter above 32k */
900#define PHY_B_IS_LCT (1<<11) /* Bit 11: counter above 128 */
901#define PHY_B_IS_AN_PR (1<<10) /* Bit 10: Page Received */
902#define PHY_B_IS_NO_HDCL (1<<9) /* Bit 9: No HCD Link */
903#define PHY_B_IS_NO_HDC (1<<8) /* Bit 8: No HCD */
904#define PHY_B_IS_NEG_USHDC (1<<7) /* Bit 7: Negotiated Unsup. HCD */
905#define PHY_B_IS_SCR_S_ER (1<<6) /* Bit 6: Scrambler Sync Error */
906#define PHY_B_IS_RRS_CHANGE (1<<5) /* Bit 5: Remote Rx Stat Change */
907#define PHY_B_IS_LRS_CHANGE (1<<4) /* Bit 4: Local Rx Stat Change */
908#define PHY_B_IS_DUP_CHANGE (1<<3) /* Bit 3: Duplex Mode Change */
909#define PHY_B_IS_LSP_CHANGE (1<<2) /* Bit 2: Link Speed Change */
910#define PHY_B_IS_LST_CHANGE (1<<1) /* Bit 1: Link Status Changed */
911#define PHY_B_IS_CRC_ER (1<<0) /* Bit 0: CRC Error */
912
913#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
914
915/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
916#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
917#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
918#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
919#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
920
921/*
922 * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
923 */
924#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */
925#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */
926/* others: 100/10: invalid for us */
927
928/*
929 * Level One-Specific
930 */
931/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
932#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
933#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
934#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
935#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
936#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
937#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
938 /* Bit 7..0: reserved */
939
940/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
941#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
942#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
943#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
944#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
945#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
946#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
947 /* Bit 9..8: reserved */
948#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
949
950/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
951#define PHY_L_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
952#define PHY_L_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
953#define PHY_L_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
954#define PHY_L_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
955 /* Bit 11..0: reserved */
956
957/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
958#define PHY_L_PC_REP_MODE (1<<15) /* Bit 15: Repeater Mode */
959 /* Bit 14: reserved */
960#define PHY_L_PC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
961#define PHY_L_PC_BY_SCR (1<<12) /* Bit 12: Bypass Scrambler */
962#define PHY_L_PC_BY_45 (1<<11) /* Bit 11: Bypass 4B5B-Decoder */
963#define PHY_L_PC_JAB_DIS (1<<10) /* Bit 10: Jabber Disabled */
964#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */
965#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */
966#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */
967#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */
968#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */
969#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */
970#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */
971#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */
972#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */
973#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */
974
975/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
976#define PHY_L_QS_D_RATE (3<<14) /* Bit 15..14: Data Rate */
977#define PHY_L_QS_TX_STAT (1<<13) /* Bit 13: Transmitting */
978#define PHY_L_QS_RX_STAT (1<<12) /* Bit 12: Receiving */
979#define PHY_L_QS_COL_STAT (1<<11) /* Bit 11: Collision */
980#define PHY_L_QS_L_STAT (1<<10) /* Bit 10: Link is up */
981#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */
982#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */
983#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */
984#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */
985#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */
986#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */
987#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */
988#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */
989
990/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
991/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
992 /* Bit 15..14: reserved */
993#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */
994 /* Bit 12: not described */
995#define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */
996#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used */
997#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade */
998#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */
999#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */
1000#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */
1001#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */
1002#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */
1003#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */
1004#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */
1005#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */
1006#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */
1007
1008/* int. mask */
1009#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
1010
1011/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
1012#define PHY_L_LC_LEDC (3<<14) /* Bit 15..14: Col/Blink/On/Off */
1013#define PHY_L_LC_LEDR (3<<12) /* Bit 13..12: Rx/Blink/On/Off */
1014#define PHY_L_LC_LEDT (3<<10) /* Bit 11..10: Tx/Blink/On/Off */
1015#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */
1016#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */
1017#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */
1018#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */
1019#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */
1020#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */
1021
1022/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
1023#define PHY_L_PC_TX_TCLK (1<<15) /* Bit 15: Enable TX_TCLK */
1024 /* Bit 14: reserved */
1025#define PHY_L_PC_ALT_NP (1<<13) /* Bit 14: Alternate Next Page */
1026#define PHY_L_PC_GMII_ALT (1<<12) /* Bit 13: Alternate GMII driver */
1027 /* Bit 11: reserved */
1028#define PHY_L_PC_TEN_CRS (1<<10) /* Bit 10: Extend CRS*/
1029 /* Bit 9..0: not described */
1030
1031/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
1032#define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */
1033#define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */
1034
1035
1036/*
1037 * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
1038 */
1039#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
1040#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
1041#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
1042#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
1043
1044
1045/*
1046 * National-Specific
1047 */
1048/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1049#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
1050#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
1051#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
1052#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
1053#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
1054#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
1055#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymmetric Pause Cap. */
1056 /* Bit 6..0: reserved */
1057
1058/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
1059#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
1060#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
1061#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
1062#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/
1063#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
1064#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
1065#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */
1066 /* Bit 8: reserved */
1067#define PHY_N_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
1068
1069/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
1070#define PHY_N_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
1071#define PHY_N_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
1072#define PHY_N_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
1073#define PHY_N_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
1074 /* Bit 11..0: reserved */
1075
1076/* todo: those are still missing */
1077/***** PHY_NAT_EXT_CTRL1 16 bit r/o Extended Control Reg1 *****/
1078/***** PHY_NAT_Q_STAT1 16 bit r/o Quick Status Reg1 *****/
1079/***** PHY_NAT_10B_OP 16 bit r/o 10Base-T Operations Reg *****/
1080/***** PHY_NAT_EXT_CTRL2 16 bit r/o Extended Control Reg1 *****/
1081/***** PHY_NAT_Q_STAT2 16 bit r/o Quick Status Reg2 *****/
1082/***** PHY_NAT_PHY_ADDR 16 bit r/o PHY Address Register *****/
1083
1084/*
1085 * Marvell-Specific
1086 */
1087/***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
1088/***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/
1089#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */
1090#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */
1091#define PHY_M_AN_RF BIT_13 /* Remote Fault */
1092 /* Bit 12: reserved */
1093#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */
1094#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */
1095#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */
1096#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */
1097#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */
1098#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */
1099
1100/* special defines for FIBER (88E1011S only) */
1101#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */
1102#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */
1103#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */
1104#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */
1105
1106/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
1107#define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */
1108#define PHY_M_P_SYM_MD_X (1<<7) /* Bit 8.. 7: symmetric Pause Mode */
1109#define PHY_M_P_ASYM_MD_X (2<<7) /* Bit 8.. 7: asymmetric Pause Mode */
1110#define PHY_M_P_BOTH_MD_X (3<<7) /* Bit 8.. 7: both Pause Mode */
1111
1112/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1113#define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
1114#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */
1115#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */
1116#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */
1117#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
1118#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
1119 /* Bit 7..0: reserved */
1120
1121/***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/
1122#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */
1123#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */
1124#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */
1125#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */
1126#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */
1127#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */
1128#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */
1129#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */
1130#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */
1131#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */
1132#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */
1133#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */
1134
1135#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */
1136#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */
1137
1138#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x)
1139#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */
1140#define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */
1141#define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */
1142
1143/***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/
1144#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */
1145#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */
1146#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */
1147#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */
1148#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */
1149#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */
1150#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */
1151#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */
1152#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */
1153#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */
1154#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */
1155#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */
1156#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */
1157#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */
1158#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */
1159#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */
1160
1161#define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
1162
1163/***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
1164/***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/
1165#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */
1166#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */
1167#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */
1168#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */
1169#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */
1170#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */
1171#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */
1172#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */
1173#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */
1174#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */
1175#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */
1176#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */
1177 /* Bit 3..2: reserved */
1178#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */
1179#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */
1180
1181#define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
1182 PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
1183
1184/***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/
1185#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */
1186#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */
1187#define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */
1188#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */
1189
1190#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */
1191#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */
1192#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */
1193
1194#define MAC_TX_CLK_0_MHZ 2
1195#define MAC_TX_CLK_2_5_MHZ 6
1196#define MAC_TX_CLK_25_MHZ 7
1197
1198/***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/
1199#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */
1200#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */
1201#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */
1202#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */
1203 /* Bit 7.. 5: reserved */
1204#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */
1205#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */
1206#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */
1207#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */
1208
1209#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */
1210
1211#define PULS_NO_STR 0 /* no pulse stretching */
1212#define PULS_21MS 1 /* 21 ms to 42 ms */
1213#define PULS_42MS 2 /* 42 ms to 84 ms */
1214#define PULS_84MS 3 /* 84 ms to 170 ms */
1215#define PULS_170MS 4 /* 170 ms to 340 ms */
1216#define PULS_340MS 5 /* 340 ms to 670 ms */
1217#define PULS_670MS 6 /* 670 ms to 1.3 s */
1218#define PULS_1300MS 7 /* 1.3 s to 2.7 s */
1219
1220#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */
1221
1222#define BLINK_42MS 0 /* 42 ms */
1223#define BLINK_84MS 1 /* 84 ms */
1224#define BLINK_170MS 2 /* 170 ms */
1225#define BLINK_340MS 3 /* 340 ms */
1226#define BLINK_670MS 4 /* 670 ms */
1227 /* values 5 - 7: reserved */
1228
1229/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
1230#define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */
1231#define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */
1232#define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */
1233#define PHY_M_LED_MO_1000(x) SHIFT4(x) /* Bit 5.. 4: Link 1000 */
1234#define PHY_M_LED_MO_RX(x) SHIFT2(x) /* Bit 3.. 2: Rx */
1235#define PHY_M_LED_MO_TX(x) SHIFT0(x) /* Bit 1.. 0: Tx */
1236
1237#define MO_LED_NORM 0
1238#define MO_LED_BLINK 1
1239#define MO_LED_OFF 2
1240#define MO_LED_ON 3
1241
1242/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
1243 /* Bit 15.. 7: reserved */
1244#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */
1245#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */
1246#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */
1247#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */
1248#define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */
1249
1250/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/
1251#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */
1252#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */
1253#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */
1254#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */
1255#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */
1256#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */
1257 /* Bit 9..4: reserved */
1258#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */
1259#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
1260
1261
1262/***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/
1263#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */
1264#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */
1265 /* Bit 12.. 8: reserved */
1266#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */
1267
1268/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
1269#define CABD_STAT_NORMAL 0
1270#define CABD_STAT_SHORT 1
1271#define CABD_STAT_OPEN 2
1272#define CABD_STAT_FAIL 3
1273
1274
1275/*
1276 * GMAC registers
1277 *
1278 * The GMAC registers are 16 or 32 bits wide.
1279 * The GMACs host processor interface is 16 bits wide,
1280 * therefore ALL registers will be addressed with 16 bit accesses.
1281 *
1282 * The following macros are provided to access the GMAC registers
1283 * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
1284 * GM_INHASH(), and GM_OUTHASH().
1285 * The macros are defined in SkGeHw.h.
1286 *
1287 * Note: NA reg = Network Address e.g DA, SA etc.
1288 *
1289 */
1290
1291/* Port Registers */
1292#define GM_GP_STAT 0x0000 /* 16 bit r/o General Purpose Status */
1293#define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */
1294#define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */
1295#define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */
1296#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow-Control */
1297#define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */
1298#define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */
1299
1300/* Source Address Registers */
1301#define GM_SRC_ADDR_1L 0x001c /* 16 bit r/w Source Address 1 (low) */
1302#define GM_SRC_ADDR_1M 0x0020 /* 16 bit r/w Source Address 1 (middle) */
1303#define GM_SRC_ADDR_1H 0x0024 /* 16 bit r/w Source Address 1 (high) */
1304#define GM_SRC_ADDR_2L 0x0028 /* 16 bit r/w Source Address 2 (low) */
1305#define GM_SRC_ADDR_2M 0x002c /* 16 bit r/w Source Address 2 (middle) */
1306#define GM_SRC_ADDR_2H 0x0030 /* 16 bit r/w Source Address 2 (high) */
1307
1308/* Multicast Address Hash Registers */
1309#define GM_MC_ADDR_H1 0x0034 /* 16 bit r/w Multicast Address Hash 1 */
1310#define GM_MC_ADDR_H2 0x0038 /* 16 bit r/w Multicast Address Hash 2 */
1311#define GM_MC_ADDR_H3 0x003c /* 16 bit r/w Multicast Address Hash 3 */
1312#define GM_MC_ADDR_H4 0x0040 /* 16 bit r/w Multicast Address Hash 4 */
1313
1314/* Interrupt Source Registers */
1315#define GM_TX_IRQ_SRC 0x0044 /* 16 bit r/o Tx Overflow IRQ Source */
1316#define GM_RX_IRQ_SRC 0x0048 /* 16 bit r/o Rx Overflow IRQ Source */
1317#define GM_TR_IRQ_SRC 0x004c /* 16 bit r/o Tx/Rx Over. IRQ Source */
1318
1319/* Interrupt Mask Registers */
1320#define GM_TX_IRQ_MSK 0x0050 /* 16 bit r/w Tx Overflow IRQ Mask */
1321#define GM_RX_IRQ_MSK 0x0054 /* 16 bit r/w Rx Overflow IRQ Mask */
1322#define GM_TR_IRQ_MSK 0x0058 /* 16 bit r/w Tx/Rx Over. IRQ Mask */
1323
1324/* Serial Management Interface (SMI) Registers */
1325#define GM_SMI_CTRL 0x0080 /* 16 bit r/w SMI Control Register */
1326#define GM_SMI_DATA 0x0084 /* 16 bit r/w SMI Data Register */
1327#define GM_PHY_ADDR 0x0088 /* 16 bit r/w GPHY Address Register */
1328
1329/* MIB Counters */
1330#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
1331#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
1332
1333/*
1334 * MIB Counters base address definitions (low word) -
1335 * use offset 4 for access to high word (32 bit r/o)
1336 */
1337#define GM_RXF_UC_OK \
1338 (GM_MIB_CNT_BASE + 0) /* Unicast Frames Received OK */
1339#define GM_RXF_BC_OK \
1340 (GM_MIB_CNT_BASE + 8) /* Broadcast Frames Received OK */
1341#define GM_RXF_MPAUSE \
1342 (GM_MIB_CNT_BASE + 16) /* Pause MAC Ctrl Frames Received */
1343#define GM_RXF_MC_OK \
1344 (GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */
1345#define GM_RXF_FCS_ERR \
1346 (GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */
1347 /* GM_MIB_CNT_BASE + 40: reserved */
1348#define GM_RXO_OK_LO \
1349 (GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */
1350#define GM_RXO_OK_HI \
1351 (GM_MIB_CNT_BASE + 56) /* Octets Received OK High */
1352#define GM_RXO_ERR_LO \
1353 (GM_MIB_CNT_BASE + 64) /* Octets Received Invalid Low */
1354#define GM_RXO_ERR_HI \
1355 (GM_MIB_CNT_BASE + 72) /* Octets Received Invalid High */
1356#define GM_RXF_SHT \
1357 (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */
1358#define GM_RXE_FRAG \
1359 (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */
1360#define GM_RXF_64B \
1361 (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */
1362#define GM_RXF_127B \
1363 (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
1364#define GM_RXF_255B \
1365 (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
1366#define GM_RXF_511B \
1367 (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
1368#define GM_RXF_1023B \
1369 (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
1370#define GM_RXF_1518B \
1371 (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
1372#define GM_RXF_MAX_SZ \
1373 (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
1374#define GM_RXF_LNG_ERR \
1375 (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
1376#define GM_RXF_JAB_PKT \
1377 (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
1378 /* GM_MIB_CNT_BASE + 168: reserved */
1379#define GM_RXE_FIFO_OV \
1380 (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
1381 /* GM_MIB_CNT_BASE + 184: reserved */
1382#define GM_TXF_UC_OK \
1383 (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
1384#define GM_TXF_BC_OK \
1385 (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
1386#define GM_TXF_MPAUSE \
1387 (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
1388#define GM_TXF_MC_OK \
1389 (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
1390#define GM_TXO_OK_LO \
1391 (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
1392#define GM_TXO_OK_HI \
1393 (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
1394#define GM_TXF_64B \
1395 (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
1396#define GM_TXF_127B \
1397 (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
1398#define GM_TXF_255B \
1399 (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
1400#define GM_TXF_511B \
1401 (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
1402#define GM_TXF_1023B \
1403 (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
1404#define GM_TXF_1518B \
1405 (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
1406#define GM_TXF_MAX_SZ \
1407 (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
1408 /* GM_MIB_CNT_BASE + 296: reserved */
1409#define GM_TXF_COL \
1410 (GM_MIB_CNT_BASE + 304) /* Tx Collision */
1411#define GM_TXF_LAT_COL \
1412 (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
1413#define GM_TXF_ABO_COL \
1414 (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
1415#define GM_TXF_MUL_COL \
1416 (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
1417#define GM_TXF_SNG_COL \
1418 (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
1419#define GM_TXE_FIFO_UR \
1420 (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
1421
1422/*----------------------------------------------------------------------------*/
1423/*
1424 * GMAC Bit Definitions
1425 *
1426 * If the bit access behaviour differs from the register access behaviour
1427 * (r/w, r/o) this is documented after the bit number.
1428 * The following bit access behaviours are used:
1429 * (sc) self clearing
1430 * (r/o) read only
1431 */
1432
1433/* GM_GP_STAT 16 bit r/o General Purpose Status Register */
1434#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */
1435#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */
1436#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */
1437#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */
1438#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */
1439#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */
1440#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */
1441#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */
1442 /* Bit 7..6: reserved */
1443#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */
1444#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */
1445#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */
1446#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */
1447#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */
1448 /* Bit 0: reserved */
1449
1450/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
1451 /* Bit 15: reserved */
1452#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */
1453#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */
1454#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */
1455#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */
1456#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */
1457#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */
1458#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */
1459#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */
1460#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */
1461#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */
1462#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */
1463#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */
1464#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */
1465#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */
1466#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */
1467
1468#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
1469#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
1470 GM_GPCR_AU_SPD_DIS)
1471
1472/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
1473#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */
1474#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */
1475#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */
1476#define GM_TXCR_COL_THR_MSK (7<<10) /* Bit 12..10: Collision Threshold */
1477
1478#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
1479
1480#define TX_COL_DEF 0x04
1481
1482/* GM_RX_CTRL 16 bit r/w Receive Control Register */
1483#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */
1484#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */
1485#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */
1486#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */
1487
1488/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
1489#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */
1490#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */
1491#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */
1492 /* Bit 3..0: reserved */
1493
1494#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
1495#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
1496#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
1497
1498#define TX_JAM_LEN_DEF 0x03
1499#define TX_JAM_IPG_DEF 0x0b
1500#define TX_IPG_JAM_DEF 0x1c
1501
1502/* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */
1503#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */
1504#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */
1505#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */
1506#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */
1507 /* Bit 7..5: reserved */
1508#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
1509
1510#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK)
1511#define DATA_BLIND_DEF 0x04
1512
1513#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK)
1514#define IPG_DATA_DEF 0x1e
1515
1516/* GM_SMI_CTRL 16 bit r/w SMI Control Register */
1517#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */
1518#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */
1519#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/
1520#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */
1521#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */
1522 /* Bit 2..0: reserved */
1523
1524#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
1525#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
1526
1527 /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */
1528 /* Bit 15..6: reserved */
1529#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */
1530#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */
1531 /* Bit 3..0: reserved */
1532
1533/* Receive Frame Status Encoding */
1534#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */
1535 /* Bit 15..14: reserved */
1536#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */
1537#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */
1538#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */
1539#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */
1540#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */
1541#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */
1542#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */
1543#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */
1544#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */
1545#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */
1546#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */
1547 /* Bit 2: reserved */
1548#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */
1549#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */
1550
1551/*
1552 * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
1553 */
1554#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
1555 GMR_FS_LONG_ERR | \
1556 GMR_FS_MII_ERR | \
1557 GMR_FS_BAD_FC | \
1558 GMR_FS_GOOD_FC | \
1559 GMR_FS_JABBER)
1560
1561/* Rx GMAC FIFO Flush Mask (default) */
1562#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \
1563 GMR_FS_RX_FF_OV | \
1564 GMR_FS_MII_ERR | \
1565 GMR_FS_BAD_FC | \
1566 GMR_FS_GOOD_FC | \
1567 GMR_FS_UN_SIZE | \
1568 GMR_FS_JABBER)
1569
1570/* typedefs *******************************************************************/
1571
1572
1573/* function prototypes ********************************************************/
1574
1575#ifdef __cplusplus
1576}
1577#endif /* __cplusplus */
1578
1579#endif /* __INC_XMAC_H */
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
deleted file mode 100644
index 6e6c56aa6d6f..000000000000
--- a/drivers/net/sk98lin/skaddr.c
+++ /dev/null
@@ -1,1788 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skaddr.c
4 * Project: Gigabit Ethernet Adapters, ADDR-Module
5 * Version: $Revision: 1.52 $
6 * Date: $Date: 2003/06/02 13:46:15 $
7 * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage multicast addresses, address override,
30 * and promiscuous mode on GEnesis and Yukon adapters.
31 *
32 * Address Layout:
33 * port address: physical MAC address
34 * 1st exact match: logical MAC address (GEnesis only)
35 * 2nd exact match: RLMT multicast (GEnesis only)
36 * exact match 3-13: OS-specific multicasts (GEnesis only)
37 *
38 * Include File Hierarchy:
39 *
40 * "skdrv1st.h"
41 * "skdrv2nd.h"
42 *
43 ******************************************************************************/
44
45#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
46static const char SysKonnectFileId[] =
47 "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
48#endif /* DEBUG ||!LINT || !SK_SLIM */
49
50#define __SKADDR_C
51
52#ifdef __cplusplus
53extern "C" {
54#endif /* cplusplus */
55
56#include "h/skdrv1st.h"
57#include "h/skdrv2nd.h"
58
59/* defines ********************************************************************/
60
61
62#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */
63#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */
64#define HASH_BITS 6 /* #bits in hash */
65#define SK_MC_BIT 0x01
66
67/* Error numbers and messages. */
68
69#define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0)
70#define SKERR_ADDR_E001MSG "Bad Flags."
71#define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1)
72#define SKERR_ADDR_E002MSG "New Error."
73
74/* typedefs *******************************************************************/
75
76/* None. */
77
78/* global variables ***********************************************************/
79
80/* 64-bit hash values with all bits set. */
81
82static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
83
84/* local variables ************************************************************/
85
86#ifdef DEBUG
87static int Next0[SK_MAX_MACS] = {0};
88#endif /* DEBUG */
89
90static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
91 SK_MAC_ADDR *pMc, int Flags);
92static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
93 int Flags);
94static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
95static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
96 SK_U32 PortNumber, int NewPromMode);
97static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
98 SK_MAC_ADDR *pMc, int Flags);
99static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
100 int Flags);
101static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
102static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
103 SK_U32 PortNumber, int NewPromMode);
104
105/* functions ******************************************************************/
106
107/******************************************************************************
108 *
109 * SkAddrInit - initialize data, set state to init
110 *
111 * Description:
112 *
113 * SK_INIT_DATA
114 * ============
115 *
116 * This routine clears the multicast tables and resets promiscuous mode.
117 * Some entries are reserved for the "logical MAC address", the
118 * SK-RLMT multicast address, and the BPDU multicast address.
119 *
120 *
121 * SK_INIT_IO
122 * ==========
123 *
124 * All permanent MAC addresses are read from EPROM.
125 * If the current MAC addresses are not already set in software,
126 * they are set to the values of the permanent addresses.
127 * The current addresses are written to the corresponding MAC.
128 *
129 *
130 * SK_INIT_RUN
131 * ===========
132 *
133 * Nothing.
134 *
135 * Context:
136 * init, pageable
137 *
138 * Returns:
139 * SK_ADDR_SUCCESS
140 */
141int SkAddrInit(
142SK_AC *pAC, /* the adapter context */
143SK_IOC IoC, /* I/O context */
144int Level) /* initialization level */
145{
146 int j;
147 SK_U32 i;
148 SK_U8 *InAddr;
149 SK_U16 *OutAddr;
150 SK_ADDR_PORT *pAPort;
151
152 switch (Level) {
153 case SK_INIT_DATA:
154 SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0,
155 (SK_U16) sizeof(SK_ADDR));
156
157 for (i = 0; i < SK_MAX_MACS; i++) {
158 pAPort = &pAC->Addr.Port[i];
159 pAPort->PromMode = SK_PROM_MODE_NONE;
160
161 pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
162 pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
163 pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
164 pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
165 }
166#ifdef xDEBUG
167 for (i = 0; i < SK_MAX_MACS; i++) {
168 if (pAC->Addr.Port[i].NextExactMatchRlmt <
169 SK_ADDR_FIRST_MATCH_RLMT) {
170 Next0[i] |= 4;
171 }
172 }
173#endif /* DEBUG */
174 /* pAC->Addr.InitDone = SK_INIT_DATA; */
175 break;
176
177 case SK_INIT_IO:
178#ifndef SK_NO_RLMT
179 for (i = 0; i < SK_MAX_NETS; i++) {
180 pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
181 }
182#endif /* !SK_NO_RLMT */
183#ifdef xDEBUG
184 for (i = 0; i < SK_MAX_MACS; i++) {
185 if (pAC->Addr.Port[i].NextExactMatchRlmt <
186 SK_ADDR_FIRST_MATCH_RLMT) {
187 Next0[i] |= 8;
188 }
189 }
190#endif /* DEBUG */
191
192 /* Read permanent logical MAC address from Control Register File. */
193 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
194 InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
195 SK_IN8(IoC, B2_MAC_1 + j, InAddr);
196 }
197
198 if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
199 /* Set the current logical MAC address to the permanent one. */
200 pAC->Addr.Net[0].CurrentMacAddress =
201 pAC->Addr.Net[0].PermanentMacAddress;
202 pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
203 }
204
205 /* Set the current logical MAC address. */
206 pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
207 pAC->Addr.Net[0].CurrentMacAddress;
208#if SK_MAX_NETS > 1
209 /* Set logical MAC address for net 2 to (log | 3). */
210 if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
211 pAC->Addr.Net[1].PermanentMacAddress =
212 pAC->Addr.Net[0].PermanentMacAddress;
213 pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
214 /* Set the current logical MAC address to the permanent one. */
215 pAC->Addr.Net[1].CurrentMacAddress =
216 pAC->Addr.Net[1].PermanentMacAddress;
217 pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
218 }
219#endif /* SK_MAX_NETS > 1 */
220
221#ifdef DEBUG
222 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
223 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
224 ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
225 i,
226 pAC->Addr.Net[i].PermanentMacAddress.a[0],
227 pAC->Addr.Net[i].PermanentMacAddress.a[1],
228 pAC->Addr.Net[i].PermanentMacAddress.a[2],
229 pAC->Addr.Net[i].PermanentMacAddress.a[3],
230 pAC->Addr.Net[i].PermanentMacAddress.a[4],
231 pAC->Addr.Net[i].PermanentMacAddress.a[5]))
232
233 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
234 ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
235 i,
236 pAC->Addr.Net[i].CurrentMacAddress.a[0],
237 pAC->Addr.Net[i].CurrentMacAddress.a[1],
238 pAC->Addr.Net[i].CurrentMacAddress.a[2],
239 pAC->Addr.Net[i].CurrentMacAddress.a[3],
240 pAC->Addr.Net[i].CurrentMacAddress.a[4],
241 pAC->Addr.Net[i].CurrentMacAddress.a[5]))
242 }
243#endif /* DEBUG */
244
245 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
246 pAPort = &pAC->Addr.Port[i];
247
248 /* Read permanent port addresses from Control Register File. */
249 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
250 InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
251 SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
252 }
253
254 if (!pAPort->CurrentMacAddressSet) {
255 /*
256 * Set the current and previous physical MAC address
257 * of this port to its permanent MAC address.
258 */
259 pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
260 pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
261 pAPort->CurrentMacAddressSet = SK_TRUE;
262 }
263
264 /* Set port's current physical MAC address. */
265 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
266#ifdef GENESIS
267 if (pAC->GIni.GIGenesis) {
268 XM_OUTADDR(IoC, i, XM_SA, OutAddr);
269 }
270#endif /* GENESIS */
271#ifdef YUKON
272 if (!pAC->GIni.GIGenesis) {
273 GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
274 }
275#endif /* YUKON */
276#ifdef DEBUG
277 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
278 ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
279 pAPort->PermanentMacAddress.a[0],
280 pAPort->PermanentMacAddress.a[1],
281 pAPort->PermanentMacAddress.a[2],
282 pAPort->PermanentMacAddress.a[3],
283 pAPort->PermanentMacAddress.a[4],
284 pAPort->PermanentMacAddress.a[5]))
285
286 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
287 ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
288 pAPort->CurrentMacAddress.a[0],
289 pAPort->CurrentMacAddress.a[1],
290 pAPort->CurrentMacAddress.a[2],
291 pAPort->CurrentMacAddress.a[3],
292 pAPort->CurrentMacAddress.a[4],
293 pAPort->CurrentMacAddress.a[5]))
294#endif /* DEBUG */
295 }
296 /* pAC->Addr.InitDone = SK_INIT_IO; */
297 break;
298
299 case SK_INIT_RUN:
300#ifdef xDEBUG
301 for (i = 0; i < SK_MAX_MACS; i++) {
302 if (pAC->Addr.Port[i].NextExactMatchRlmt <
303 SK_ADDR_FIRST_MATCH_RLMT) {
304 Next0[i] |= 16;
305 }
306 }
307#endif /* DEBUG */
308
309 /* pAC->Addr.InitDone = SK_INIT_RUN; */
310 break;
311
312 default: /* error */
313 break;
314 }
315
316 return (SK_ADDR_SUCCESS);
317
318} /* SkAddrInit */
319
320#ifndef SK_SLIM
321
322/******************************************************************************
323 *
324 * SkAddrMcClear - clear the multicast table
325 *
326 * Description:
327 * This routine clears the multicast table.
328 *
329 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
330 * immediately.
331 *
332 * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
333 * to the adapter in use. The real work is done there.
334 *
335 * Context:
336 * runtime, pageable
337 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
338 * may be called after SK_INIT_IO without limitation
339 *
340 * Returns:
341 * SK_ADDR_SUCCESS
342 * SK_ADDR_ILLEGAL_PORT
343 */
344int SkAddrMcClear(
345SK_AC *pAC, /* adapter context */
346SK_IOC IoC, /* I/O context */
347SK_U32 PortNumber, /* Index of affected port */
348int Flags) /* permanent/non-perm, sw-only */
349{
350 int ReturnCode;
351
352 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
353 return (SK_ADDR_ILLEGAL_PORT);
354 }
355
356 if (pAC->GIni.GIGenesis) {
357 ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
358 }
359 else {
360 ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
361 }
362
363 return (ReturnCode);
364
365} /* SkAddrMcClear */
366
367#endif /* !SK_SLIM */
368
369#ifndef SK_SLIM
370
371/******************************************************************************
372 *
373 * SkAddrXmacMcClear - clear the multicast table
374 *
375 * Description:
376 * This routine clears the multicast table
377 * (either entry 2 or entries 3-16 and InexactFilter) of the given port.
378 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
379 * immediately.
380 *
381 * Context:
382 * runtime, pageable
383 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
384 * may be called after SK_INIT_IO without limitation
385 *
386 * Returns:
387 * SK_ADDR_SUCCESS
388 * SK_ADDR_ILLEGAL_PORT
389 */
390static int SkAddrXmacMcClear(
391SK_AC *pAC, /* adapter context */
392SK_IOC IoC, /* I/O context */
393SK_U32 PortNumber, /* Index of affected port */
394int Flags) /* permanent/non-perm, sw-only */
395{
396 int i;
397
398 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
399
400 /* Clear RLMT multicast addresses. */
401 pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
402 }
403 else { /* not permanent => DRV */
404
405 /* Clear InexactFilter */
406 for (i = 0; i < 8; i++) {
407 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
408 }
409
410 /* Clear DRV multicast addresses. */
411
412 pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
413 }
414
415 if (!(Flags & SK_MC_SW_ONLY)) {
416 (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
417 }
418
419 return (SK_ADDR_SUCCESS);
420
421} /* SkAddrXmacMcClear */
422
423#endif /* !SK_SLIM */
424
425#ifndef SK_SLIM
426
427/******************************************************************************
428 *
429 * SkAddrGmacMcClear - clear the multicast table
430 *
431 * Description:
432 * This routine clears the multicast hashing table (InexactFilter)
433 * (either the RLMT or the driver bits) of the given port.
434 *
435 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
436 * immediately.
437 *
438 * Context:
439 * runtime, pageable
440 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
441 * may be called after SK_INIT_IO without limitation
442 *
443 * Returns:
444 * SK_ADDR_SUCCESS
445 * SK_ADDR_ILLEGAL_PORT
446 */
447static int SkAddrGmacMcClear(
448SK_AC *pAC, /* adapter context */
449SK_IOC IoC, /* I/O context */
450SK_U32 PortNumber, /* Index of affected port */
451int Flags) /* permanent/non-perm, sw-only */
452{
453 int i;
454
455#ifdef DEBUG
456 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
457 ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
458 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
459 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
460 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
461 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
462 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
463 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
464 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
465 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
466#endif /* DEBUG */
467
468 /* Clear InexactFilter */
469 for (i = 0; i < 8; i++) {
470 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
471 }
472
473 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
474
475 /* Copy DRV bits to InexactFilter. */
476 for (i = 0; i < 8; i++) {
477 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
478 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
479
480 /* Clear InexactRlmtFilter. */
481 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
482
483 }
484 }
485 else { /* not permanent => DRV */
486
487 /* Copy RLMT bits to InexactFilter. */
488 for (i = 0; i < 8; i++) {
489 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
490 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
491
492 /* Clear InexactDrvFilter. */
493 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
494 }
495 }
496
497#ifdef DEBUG
498 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
499 ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
500 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
501 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
502 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
503 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
504 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
505 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
506 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
507 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
508#endif /* DEBUG */
509
510 if (!(Flags & SK_MC_SW_ONLY)) {
511 (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
512 }
513
514 return (SK_ADDR_SUCCESS);
515
516} /* SkAddrGmacMcClear */
517
518#ifndef SK_ADDR_CHEAT
519
520/******************************************************************************
521 *
522 * SkXmacMcHash - hash multicast address
523 *
524 * Description:
525 * This routine computes the hash value for a multicast address.
526 * A CRC32 algorithm is used.
527 *
528 * Notes:
529 * The code was adapted from the XaQti data sheet.
530 *
531 * Context:
532 * runtime, pageable
533 *
534 * Returns:
535 * Hash value of multicast address.
536 */
537static SK_U32 SkXmacMcHash(
538unsigned char *pMc) /* Multicast address */
539{
540 SK_U32 Idx;
541 SK_U32 Bit;
542 SK_U32 Data;
543 SK_U32 Crc;
544
545 Crc = 0xFFFFFFFFUL;
546 for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
547 Data = *pMc++;
548 for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
549 Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
550 }
551 }
552
553 return (Crc & ((1 << HASH_BITS) - 1));
554
555} /* SkXmacMcHash */
556
557
558/******************************************************************************
559 *
560 * SkGmacMcHash - hash multicast address
561 *
562 * Description:
563 * This routine computes the hash value for a multicast address.
564 * A CRC16 algorithm is used.
565 *
566 * Notes:
567 *
568 *
569 * Context:
570 * runtime, pageable
571 *
572 * Returns:
573 * Hash value of multicast address.
574 */
575static SK_U32 SkGmacMcHash(
576unsigned char *pMc) /* Multicast address */
577{
578 SK_U32 Data;
579 SK_U32 TmpData;
580 SK_U32 Crc;
581 int Byte;
582 int Bit;
583
584 Crc = 0xFFFFFFFFUL;
585 for (Byte = 0; Byte < 6; Byte++) {
586 /* Get next byte. */
587 Data = (SK_U32) pMc[Byte];
588
589 /* Change bit order in byte. */
590 TmpData = Data;
591 for (Bit = 0; Bit < 8; Bit++) {
592 if (TmpData & 1L) {
593 Data |= 1L << (7 - Bit);
594 }
595 else {
596 Data &= ~(1L << (7 - Bit));
597 }
598 TmpData >>= 1;
599 }
600
601 Crc ^= (Data << 24);
602 for (Bit = 0; Bit < 8; Bit++) {
603 if (Crc & 0x80000000) {
604 Crc = (Crc << 1) ^ GMAC_POLY;
605 }
606 else {
607 Crc <<= 1;
608 }
609 }
610 }
611
612 return (Crc & ((1 << HASH_BITS) - 1));
613
614} /* SkGmacMcHash */
615
616#endif /* !SK_ADDR_CHEAT */
617
618/******************************************************************************
619 *
620 * SkAddrMcAdd - add a multicast address to a port
621 *
622 * Description:
623 * This routine enables reception for a given address on the given port.
624 *
625 * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
626 * adapter in use. The real work is done there.
627 *
628 * Notes:
629 * The return code is only valid for SK_PROM_MODE_NONE.
630 *
631 * Context:
632 * runtime, pageable
633 * may be called after SK_INIT_DATA
634 *
635 * Returns:
636 * SK_MC_FILTERING_EXACT
637 * SK_MC_FILTERING_INEXACT
638 * SK_MC_ILLEGAL_ADDRESS
639 * SK_MC_ILLEGAL_PORT
640 * SK_MC_RLMT_OVERFLOW
641 */
642int SkAddrMcAdd(
643SK_AC *pAC, /* adapter context */
644SK_IOC IoC, /* I/O context */
645SK_U32 PortNumber, /* Port Number */
646SK_MAC_ADDR *pMc, /* multicast address to be added */
647int Flags) /* permanent/non-permanent */
648{
649 int ReturnCode;
650
651 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
652 return (SK_ADDR_ILLEGAL_PORT);
653 }
654
655 if (pAC->GIni.GIGenesis) {
656 ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
657 }
658 else {
659 ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
660 }
661
662 return (ReturnCode);
663
664} /* SkAddrMcAdd */
665
666
667/******************************************************************************
668 *
669 * SkAddrXmacMcAdd - add a multicast address to a port
670 *
671 * Description:
672 * This routine enables reception for a given address on the given port.
673 *
674 * Notes:
675 * The return code is only valid for SK_PROM_MODE_NONE.
676 *
677 * The multicast bit is only checked if there are no free exact match
678 * entries.
679 *
680 * Context:
681 * runtime, pageable
682 * may be called after SK_INIT_DATA
683 *
684 * Returns:
685 * SK_MC_FILTERING_EXACT
686 * SK_MC_FILTERING_INEXACT
687 * SK_MC_ILLEGAL_ADDRESS
688 * SK_MC_RLMT_OVERFLOW
689 */
690static int SkAddrXmacMcAdd(
691SK_AC *pAC, /* adapter context */
692SK_IOC IoC, /* I/O context */
693SK_U32 PortNumber, /* Port Number */
694SK_MAC_ADDR *pMc, /* multicast address to be added */
695int Flags) /* permanent/non-permanent */
696{
697 int i;
698 SK_U8 Inexact;
699#ifndef SK_ADDR_CHEAT
700 SK_U32 HashBit;
701#endif /* !defined(SK_ADDR_CHEAT) */
702
703 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
704#ifdef xDEBUG
705 if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
706 SK_ADDR_FIRST_MATCH_RLMT) {
707 Next0[PortNumber] |= 1;
708 return (SK_MC_RLMT_OVERFLOW);
709 }
710#endif /* DEBUG */
711
712 if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
713 SK_ADDR_LAST_MATCH_RLMT) {
714 return (SK_MC_RLMT_OVERFLOW);
715 }
716
717 /* Set a RLMT multicast address. */
718
719 pAC->Addr.Port[PortNumber].Exact[
720 pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
721
722 return (SK_MC_FILTERING_EXACT);
723 }
724
725#ifdef xDEBUG
726 if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
727 SK_ADDR_FIRST_MATCH_DRV) {
728 Next0[PortNumber] |= 2;
729 return (SK_MC_RLMT_OVERFLOW);
730 }
731#endif /* DEBUG */
732
733 if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
734
735 /* Set exact match entry. */
736 pAC->Addr.Port[PortNumber].Exact[
737 pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
738
739 /* Clear InexactFilter */
740 for (i = 0; i < 8; i++) {
741 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
742 }
743 }
744 else {
745 if (!(pMc->a[0] & SK_MC_BIT)) {
746 /* Hashing only possible with multicast addresses */
747 return (SK_MC_ILLEGAL_ADDRESS);
748 }
749#ifndef SK_ADDR_CHEAT
750 /* Compute hash value of address. */
751 HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
752
753 /* Add bit to InexactFilter. */
754 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
755 1 << (HashBit % 8);
756#else /* SK_ADDR_CHEAT */
757 /* Set all bits in InexactFilter. */
758 for (i = 0; i < 8; i++) {
759 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
760 }
761#endif /* SK_ADDR_CHEAT */
762 }
763
764 for (Inexact = 0, i = 0; i < 8; i++) {
765 Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
766 }
767
768 if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
769 return (SK_MC_FILTERING_EXACT);
770 }
771 else {
772 return (SK_MC_FILTERING_INEXACT);
773 }
774
775} /* SkAddrXmacMcAdd */
776
777
778/******************************************************************************
779 *
780 * SkAddrGmacMcAdd - add a multicast address to a port
781 *
782 * Description:
783 * This routine enables reception for a given address on the given port.
784 *
785 * Notes:
786 * The return code is only valid for SK_PROM_MODE_NONE.
787 *
788 * Context:
789 * runtime, pageable
790 * may be called after SK_INIT_DATA
791 *
792 * Returns:
793 * SK_MC_FILTERING_INEXACT
794 * SK_MC_ILLEGAL_ADDRESS
795 */
796static int SkAddrGmacMcAdd(
797SK_AC *pAC, /* adapter context */
798SK_IOC IoC, /* I/O context */
799SK_U32 PortNumber, /* Port Number */
800SK_MAC_ADDR *pMc, /* multicast address to be added */
801int Flags) /* permanent/non-permanent */
802{
803 int i;
804#ifndef SK_ADDR_CHEAT
805 SK_U32 HashBit;
806#endif /* !defined(SK_ADDR_CHEAT) */
807
808 if (!(pMc->a[0] & SK_MC_BIT)) {
809 /* Hashing only possible with multicast addresses */
810 return (SK_MC_ILLEGAL_ADDRESS);
811 }
812
813#ifndef SK_ADDR_CHEAT
814
815 /* Compute hash value of address. */
816 HashBit = SkGmacMcHash(&pMc->a[0]);
817
818 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
819
820 /* Add bit to InexactRlmtFilter. */
821 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
822 1 << (HashBit % 8);
823
824 /* Copy bit to InexactFilter. */
825 for (i = 0; i < 8; i++) {
826 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
827 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
828 }
829#ifdef DEBUG
830 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
831 ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
832 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
833 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
834 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
835 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
836 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
837 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
838 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
839 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
840#endif /* DEBUG */
841 }
842 else { /* not permanent => DRV */
843
844 /* Add bit to InexactDrvFilter. */
845 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
846 1 << (HashBit % 8);
847
848 /* Copy bit to InexactFilter. */
849 for (i = 0; i < 8; i++) {
850 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
851 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
852 }
853#ifdef DEBUG
854 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
855 ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
856 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
857 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
858 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
859 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
860 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
861 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
862 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
863 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
864#endif /* DEBUG */
865 }
866
867#else /* SK_ADDR_CHEAT */
868
869 /* Set all bits in InexactFilter. */
870 for (i = 0; i < 8; i++) {
871 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
872 }
873#endif /* SK_ADDR_CHEAT */
874
875 return (SK_MC_FILTERING_INEXACT);
876
877} /* SkAddrGmacMcAdd */
878
879#endif /* !SK_SLIM */
880
881/******************************************************************************
882 *
883 * SkAddrMcUpdate - update the HW MC address table and set the MAC address
884 *
885 * Description:
886 * This routine enables reception of the addresses contained in a local
887 * table for a given port.
888 * It also programs the port's current physical MAC address.
889 *
890 * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
891 * to the adapter in use. The real work is done there.
892 *
893 * Notes:
894 * The return code is only valid for SK_PROM_MODE_NONE.
895 *
896 * Context:
897 * runtime, pageable
898 * may be called after SK_INIT_IO
899 *
900 * Returns:
901 * SK_MC_FILTERING_EXACT
902 * SK_MC_FILTERING_INEXACT
903 * SK_ADDR_ILLEGAL_PORT
904 */
905int SkAddrMcUpdate(
906SK_AC *pAC, /* adapter context */
907SK_IOC IoC, /* I/O context */
908SK_U32 PortNumber) /* Port Number */
909{
910 int ReturnCode = 0;
911#if (!defined(SK_SLIM) || defined(DEBUG))
912 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
913 return (SK_ADDR_ILLEGAL_PORT);
914 }
915#endif /* !SK_SLIM || DEBUG */
916
917#ifdef GENESIS
918 if (pAC->GIni.GIGenesis) {
919 ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
920 }
921#endif /* GENESIS */
922#ifdef YUKON
923 if (!pAC->GIni.GIGenesis) {
924 ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
925 }
926#endif /* YUKON */
927 return (ReturnCode);
928
929} /* SkAddrMcUpdate */
930
931
932#ifdef GENESIS
933
934/******************************************************************************
935 *
936 * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
937 *
938 * Description:
939 * This routine enables reception of the addresses contained in a local
940 * table for a given port.
941 * It also programs the port's current physical MAC address.
942 *
943 * Notes:
944 * The return code is only valid for SK_PROM_MODE_NONE.
945 *
946 * Context:
947 * runtime, pageable
948 * may be called after SK_INIT_IO
949 *
950 * Returns:
951 * SK_MC_FILTERING_EXACT
952 * SK_MC_FILTERING_INEXACT
953 * SK_ADDR_ILLEGAL_PORT
954 */
955static int SkAddrXmacMcUpdate(
956SK_AC *pAC, /* adapter context */
957SK_IOC IoC, /* I/O context */
958SK_U32 PortNumber) /* Port Number */
959{
960 SK_U32 i;
961 SK_U8 Inexact;
962 SK_U16 *OutAddr;
963 SK_ADDR_PORT *pAPort;
964
965 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
966 ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
967
968 pAPort = &pAC->Addr.Port[PortNumber];
969
970#ifdef DEBUG
971 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
972 ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
973#endif /* DEBUG */
974
975 /* Start with 0 to also program the logical MAC address. */
976 for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
977 /* Set exact match address i on XMAC */
978 OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
979 XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
980 }
981
982 /* Clear other permanent exact match addresses on XMAC */
983 if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
984
985 SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
986 SK_ADDR_LAST_MATCH_RLMT);
987 }
988
989 for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
990 OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
991 XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
992 }
993
994 /* Clear other non-permanent exact match addresses on XMAC */
995 if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
996
997 SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
998 SK_ADDR_LAST_MATCH_DRV);
999 }
1000
1001 for (Inexact = 0, i = 0; i < 8; i++) {
1002 Inexact |= pAPort->InexactFilter.Bytes[i];
1003 }
1004
1005 if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
1006
1007 /* Set all bits in 64-bit hash register. */
1008 XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
1009
1010 /* Enable Hashing */
1011 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1012 }
1013 else if (Inexact != 0) {
1014
1015 /* Set 64-bit hash register to InexactFilter. */
1016 XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
1017
1018 /* Enable Hashing */
1019 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1020 }
1021 else {
1022 /* Disable Hashing */
1023 SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
1024 }
1025
1026 if (pAPort->PromMode != SK_PROM_MODE_NONE) {
1027 (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1028 }
1029
1030 /* Set port's current physical MAC address. */
1031 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
1032
1033 XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
1034
1035#ifdef xDEBUG
1036 for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
1037 SK_U8 InAddr8[6];
1038 SK_U16 *InAddr;
1039
1040 /* Get exact match address i from port PortNumber. */
1041 InAddr = (SK_U16 *) &InAddr8[0];
1042
1043 XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
1044
1045 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1046 ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
1047 "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
1048 i,
1049 PortNumber,
1050 InAddr8[0],
1051 InAddr8[1],
1052 InAddr8[2],
1053 InAddr8[3],
1054 InAddr8[4],
1055 InAddr8[5],
1056 pAPort->Exact[i].a[0],
1057 pAPort->Exact[i].a[1],
1058 pAPort->Exact[i].a[2],
1059 pAPort->Exact[i].a[3],
1060 pAPort->Exact[i].a[4],
1061 pAPort->Exact[i].a[5]))
1062 }
1063#endif /* DEBUG */
1064
1065 /* Determine return value. */
1066 if (Inexact == 0 && pAPort->PromMode == 0) {
1067 return (SK_MC_FILTERING_EXACT);
1068 }
1069 else {
1070 return (SK_MC_FILTERING_INEXACT);
1071 }
1072
1073} /* SkAddrXmacMcUpdate */
1074
1075#endif /* GENESIS */
1076
1077#ifdef YUKON
1078
1079/******************************************************************************
1080 *
1081 * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
1082 *
1083 * Description:
1084 * This routine enables reception of the addresses contained in a local
1085 * table for a given port.
1086 * It also programs the port's current physical MAC address.
1087 *
1088 * Notes:
1089 * The return code is only valid for SK_PROM_MODE_NONE.
1090 *
1091 * Context:
1092 * runtime, pageable
1093 * may be called after SK_INIT_IO
1094 *
1095 * Returns:
1096 * SK_MC_FILTERING_EXACT
1097 * SK_MC_FILTERING_INEXACT
1098 * SK_ADDR_ILLEGAL_PORT
1099 */
1100static int SkAddrGmacMcUpdate(
1101SK_AC *pAC, /* adapter context */
1102SK_IOC IoC, /* I/O context */
1103SK_U32 PortNumber) /* Port Number */
1104{
1105#ifndef SK_SLIM
1106 SK_U32 i;
1107 SK_U8 Inexact;
1108#endif /* not SK_SLIM */
1109 SK_U16 *OutAddr;
1110 SK_ADDR_PORT *pAPort;
1111
1112 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1113 ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
1114
1115 pAPort = &pAC->Addr.Port[PortNumber];
1116
1117#ifdef DEBUG
1118 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1119 ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
1120#endif /* DEBUG */
1121
1122#ifndef SK_SLIM
1123 for (Inexact = 0, i = 0; i < 8; i++) {
1124 Inexact |= pAPort->InexactFilter.Bytes[i];
1125 }
1126
1127 /* Set 64-bit hash register to InexactFilter. */
1128 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
1129 &pAPort->InexactFilter.Bytes[0]);
1130
1131 if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
1132
1133 /* Set all bits in 64-bit hash register. */
1134 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1135
1136 /* Enable Hashing */
1137 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1138 }
1139 else {
1140 /* Enable Hashing. */
1141 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1142 }
1143
1144 if (pAPort->PromMode != SK_PROM_MODE_NONE) {
1145 (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1146 }
1147#else /* SK_SLIM */
1148
1149 /* Set all bits in 64-bit hash register. */
1150 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1151
1152 /* Enable Hashing */
1153 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1154
1155 (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1156
1157#endif /* SK_SLIM */
1158
1159 /* Set port's current physical MAC address. */
1160 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
1161 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
1162
1163 /* Set port's current logical MAC address. */
1164 OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
1165 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
1166
1167#ifdef DEBUG
1168 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1169 ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1170 pAPort->Exact[0].a[0],
1171 pAPort->Exact[0].a[1],
1172 pAPort->Exact[0].a[2],
1173 pAPort->Exact[0].a[3],
1174 pAPort->Exact[0].a[4],
1175 pAPort->Exact[0].a[5]))
1176
1177 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1178 ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1179 pAPort->CurrentMacAddress.a[0],
1180 pAPort->CurrentMacAddress.a[1],
1181 pAPort->CurrentMacAddress.a[2],
1182 pAPort->CurrentMacAddress.a[3],
1183 pAPort->CurrentMacAddress.a[4],
1184 pAPort->CurrentMacAddress.a[5]))
1185#endif /* DEBUG */
1186
1187#ifndef SK_SLIM
1188 /* Determine return value. */
1189 if (Inexact == 0 && pAPort->PromMode == 0) {
1190 return (SK_MC_FILTERING_EXACT);
1191 }
1192 else {
1193 return (SK_MC_FILTERING_INEXACT);
1194 }
1195#else /* SK_SLIM */
1196 return (SK_MC_FILTERING_INEXACT);
1197#endif /* SK_SLIM */
1198
1199} /* SkAddrGmacMcUpdate */
1200
1201#endif /* YUKON */
1202
1203#ifndef SK_NO_MAO
1204
1205/******************************************************************************
1206 *
1207 * SkAddrOverride - override a port's MAC address
1208 *
1209 * Description:
1210 * This routine overrides the MAC address of one port.
1211 *
1212 * Context:
1213 * runtime, pageable
1214 * may be called after SK_INIT_IO
1215 *
1216 * Returns:
1217 * SK_ADDR_SUCCESS if successful.
1218 * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
1219 * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
1220 * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
1221 */
1222int SkAddrOverride(
1223SK_AC *pAC, /* adapter context */
1224SK_IOC IoC, /* I/O context */
1225SK_U32 PortNumber, /* Port Number */
1226SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */
1227int Flags) /* logical/physical MAC address */
1228{
1229#ifndef SK_NO_RLMT
1230 SK_EVPARA Para;
1231#endif /* !SK_NO_RLMT */
1232 SK_U32 NetNumber;
1233 SK_U32 i;
1234 SK_U16 SK_FAR *OutAddr;
1235
1236#ifndef SK_NO_RLMT
1237 NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
1238#else
1239 NetNumber = 0;
1240#endif /* SK_NO_RLMT */
1241#if (!defined(SK_SLIM) || defined(DEBUG))
1242 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1243 return (SK_ADDR_ILLEGAL_PORT);
1244 }
1245#endif /* !SK_SLIM || DEBUG */
1246 if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
1247 return (SK_ADDR_MULTICAST_ADDRESS);
1248 }
1249
1250 if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
1251 return (SK_ADDR_TOO_EARLY);
1252 }
1253
1254 if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */
1255 /* Parameter *pNewAddr is ignored. */
1256 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1257 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1258 return (SK_ADDR_TOO_EARLY);
1259 }
1260 }
1261#ifndef SK_NO_RLMT
1262 /* Set PortNumber to number of net's active port. */
1263 PortNumber = pAC->Rlmt.Net[NetNumber].
1264 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1265#endif /* !SK_NO_RLMT */
1266 pAC->Addr.Port[PortNumber].Exact[0] =
1267 pAC->Addr.Net[NetNumber].CurrentMacAddress;
1268
1269 /* Write address to first exact match entry of active port. */
1270 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1271 }
1272 else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
1273 /* Deactivate logical MAC address. */
1274 /* Parameter *pNewAddr is ignored. */
1275 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1276 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1277 return (SK_ADDR_TOO_EARLY);
1278 }
1279 }
1280#ifndef SK_NO_RLMT
1281 /* Set PortNumber to number of net's active port. */
1282 PortNumber = pAC->Rlmt.Net[NetNumber].
1283 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1284#endif /* !SK_NO_RLMT */
1285 for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
1286 pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
1287 }
1288
1289 /* Write address to first exact match entry of active port. */
1290 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1291 }
1292 else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */
1293 if (SK_ADDR_EQUAL(pNewAddr->a,
1294 pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
1295 return (SK_ADDR_DUPLICATE_ADDRESS);
1296 }
1297
1298 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1299 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1300 return (SK_ADDR_TOO_EARLY);
1301 }
1302
1303 if (SK_ADDR_EQUAL(pNewAddr->a,
1304 pAC->Addr.Port[i].CurrentMacAddress.a)) {
1305 if (i == PortNumber) {
1306 return (SK_ADDR_SUCCESS);
1307 }
1308 else {
1309 return (SK_ADDR_DUPLICATE_ADDRESS);
1310 }
1311 }
1312 }
1313
1314 pAC->Addr.Port[PortNumber].PreviousMacAddress =
1315 pAC->Addr.Port[PortNumber].CurrentMacAddress;
1316 pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
1317
1318 /* Change port's physical MAC address. */
1319 OutAddr = (SK_U16 SK_FAR *) pNewAddr;
1320#ifdef GENESIS
1321 if (pAC->GIni.GIGenesis) {
1322 XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
1323 }
1324#endif /* GENESIS */
1325#ifdef YUKON
1326 if (!pAC->GIni.GIGenesis) {
1327 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
1328 }
1329#endif /* YUKON */
1330
1331#ifndef SK_NO_RLMT
1332 /* Report address change to RLMT. */
1333 Para.Para32[0] = PortNumber;
1334 Para.Para32[0] = -1;
1335 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
1336#endif /* !SK_NO_RLMT */
1337 }
1338 else { /* Logical MAC address. */
1339 if (SK_ADDR_EQUAL(pNewAddr->a,
1340 pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
1341 return (SK_ADDR_SUCCESS);
1342 }
1343
1344 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1345 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1346 return (SK_ADDR_TOO_EARLY);
1347 }
1348
1349 if (SK_ADDR_EQUAL(pNewAddr->a,
1350 pAC->Addr.Port[i].CurrentMacAddress.a)) {
1351 return (SK_ADDR_DUPLICATE_ADDRESS);
1352 }
1353 }
1354
1355 /*
1356 * In case that the physical and the logical MAC addresses are equal
1357 * we must also change the physical MAC address here.
1358 * In this case we have an adapter which initially was programmed with
1359 * two identical MAC addresses.
1360 */
1361 if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
1362 pAC->Addr.Port[PortNumber].Exact[0].a)) {
1363
1364 pAC->Addr.Port[PortNumber].PreviousMacAddress =
1365 pAC->Addr.Port[PortNumber].CurrentMacAddress;
1366 pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
1367
1368#ifndef SK_NO_RLMT
1369 /* Report address change to RLMT. */
1370 Para.Para32[0] = PortNumber;
1371 Para.Para32[0] = -1;
1372 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
1373#endif /* !SK_NO_RLMT */
1374 }
1375
1376#ifndef SK_NO_RLMT
1377 /* Set PortNumber to number of net's active port. */
1378 PortNumber = pAC->Rlmt.Net[NetNumber].
1379 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1380#endif /* !SK_NO_RLMT */
1381 pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
1382 pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
1383#ifdef DEBUG
1384 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1385 ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
1386 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
1387 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
1388 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
1389 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
1390 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
1391 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
1392
1393 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1394 ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1395 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
1396 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
1397 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
1398 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
1399 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
1400 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
1401#endif /* DEBUG */
1402
1403 /* Write address to first exact match entry of active port. */
1404 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1405 }
1406
1407 return (SK_ADDR_SUCCESS);
1408
1409} /* SkAddrOverride */
1410
1411
1412#endif /* SK_NO_MAO */
1413
1414/******************************************************************************
1415 *
1416 * SkAddrPromiscuousChange - set promiscuous mode for given port
1417 *
1418 * Description:
1419 * This routine manages promiscuous mode:
1420 * - none
1421 * - all LLC frames
1422 * - all MC frames
1423 *
1424 * It calls either SkAddrXmacPromiscuousChange or
1425 * SkAddrGmacPromiscuousChange, according to the adapter in use.
1426 * The real work is done there.
1427 *
1428 * Context:
1429 * runtime, pageable
1430 * may be called after SK_INIT_IO
1431 *
1432 * Returns:
1433 * SK_ADDR_SUCCESS
1434 * SK_ADDR_ILLEGAL_PORT
1435 */
1436int SkAddrPromiscuousChange(
1437SK_AC *pAC, /* adapter context */
1438SK_IOC IoC, /* I/O context */
1439SK_U32 PortNumber, /* port whose promiscuous mode changes */
1440int NewPromMode) /* new promiscuous mode */
1441{
1442 int ReturnCode = 0;
1443#if (!defined(SK_SLIM) || defined(DEBUG))
1444 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1445 return (SK_ADDR_ILLEGAL_PORT);
1446 }
1447#endif /* !SK_SLIM || DEBUG */
1448
1449#ifdef GENESIS
1450 if (pAC->GIni.GIGenesis) {
1451 ReturnCode =
1452 SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
1453 }
1454#endif /* GENESIS */
1455#ifdef YUKON
1456 if (!pAC->GIni.GIGenesis) {
1457 ReturnCode =
1458 SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
1459 }
1460#endif /* YUKON */
1461
1462 return (ReturnCode);
1463
1464} /* SkAddrPromiscuousChange */
1465
1466#ifdef GENESIS
1467
1468/******************************************************************************
1469 *
1470 * SkAddrXmacPromiscuousChange - set promiscuous mode for given port
1471 *
1472 * Description:
1473 * This routine manages promiscuous mode:
1474 * - none
1475 * - all LLC frames
1476 * - all MC frames
1477 *
1478 * Context:
1479 * runtime, pageable
1480 * may be called after SK_INIT_IO
1481 *
1482 * Returns:
1483 * SK_ADDR_SUCCESS
1484 * SK_ADDR_ILLEGAL_PORT
1485 */
1486static int SkAddrXmacPromiscuousChange(
1487SK_AC *pAC, /* adapter context */
1488SK_IOC IoC, /* I/O context */
1489SK_U32 PortNumber, /* port whose promiscuous mode changes */
1490int NewPromMode) /* new promiscuous mode */
1491{
1492 int i;
1493 SK_BOOL InexactModeBit;
1494 SK_U8 Inexact;
1495 SK_U8 HwInexact;
1496 SK_FILTER64 HwInexactFilter;
1497 SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */
1498 int CurPromMode = SK_PROM_MODE_NONE;
1499
1500 /* Read CurPromMode from Hardware. */
1501 XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
1502
1503 if ((LoMode & XM_MD_ENA_PROM) != 0) {
1504 /* Promiscuous mode! */
1505 CurPromMode |= SK_PROM_MODE_LLC;
1506 }
1507
1508 for (Inexact = 0xFF, i = 0; i < 8; i++) {
1509 Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
1510 }
1511 if (Inexact == 0xFF) {
1512 CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
1513 }
1514 else {
1515 /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
1516 XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
1517
1518 InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
1519
1520 /* Read 64-bit hash register from XMAC */
1521 XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
1522
1523 for (HwInexact = 0xFF, i = 0; i < 8; i++) {
1524 HwInexact &= HwInexactFilter.Bytes[i];
1525 }
1526
1527 if (InexactModeBit && (HwInexact == 0xFF)) {
1528 CurPromMode |= SK_PROM_MODE_ALL_MC;
1529 }
1530 }
1531
1532 pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
1533
1534 if (NewPromMode == CurPromMode) {
1535 return (SK_ADDR_SUCCESS);
1536 }
1537
1538 if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
1539 !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
1540
1541 /* Set all bits in 64-bit hash register. */
1542 XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
1543
1544 /* Enable Hashing */
1545 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1546 }
1547 else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
1548 !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
1549 for (Inexact = 0, i = 0; i < 8; i++) {
1550 Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
1551 }
1552 if (Inexact == 0) {
1553 /* Disable Hashing */
1554 SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
1555 }
1556 else {
1557 /* Set 64-bit hash register to InexactFilter. */
1558 XM_OUTHASH(IoC, PortNumber, XM_HSM,
1559 &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
1560
1561 /* Enable Hashing */
1562 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1563 }
1564 }
1565
1566 if ((NewPromMode & SK_PROM_MODE_LLC) &&
1567 !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
1568 /* Set the MAC in Promiscuous Mode */
1569 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
1570 }
1571 else if ((CurPromMode & SK_PROM_MODE_LLC) &&
1572 !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */
1573 /* Clear Promiscuous Mode */
1574 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
1575 }
1576
1577 return (SK_ADDR_SUCCESS);
1578
1579} /* SkAddrXmacPromiscuousChange */
1580
1581#endif /* GENESIS */
1582
1583#ifdef YUKON
1584
1585/******************************************************************************
1586 *
1587 * SkAddrGmacPromiscuousChange - set promiscuous mode for given port
1588 *
1589 * Description:
1590 * This routine manages promiscuous mode:
1591 * - none
1592 * - all LLC frames
1593 * - all MC frames
1594 *
1595 * Context:
1596 * runtime, pageable
1597 * may be called after SK_INIT_IO
1598 *
1599 * Returns:
1600 * SK_ADDR_SUCCESS
1601 * SK_ADDR_ILLEGAL_PORT
1602 */
1603static int SkAddrGmacPromiscuousChange(
1604SK_AC *pAC, /* adapter context */
1605SK_IOC IoC, /* I/O context */
1606SK_U32 PortNumber, /* port whose promiscuous mode changes */
1607int NewPromMode) /* new promiscuous mode */
1608{
1609 SK_U16 ReceiveControl; /* GMAC Receive Control Register */
1610 int CurPromMode = SK_PROM_MODE_NONE;
1611
1612 /* Read CurPromMode from Hardware. */
1613 GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
1614
1615 if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
1616 /* Promiscuous mode! */
1617 CurPromMode |= SK_PROM_MODE_LLC;
1618 }
1619
1620 if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
1621 /* All Multicast mode! */
1622 CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
1623 }
1624
1625 pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
1626
1627 if (NewPromMode == CurPromMode) {
1628 return (SK_ADDR_SUCCESS);
1629 }
1630
1631 if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
1632 !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
1633
1634 /* Set all bits in 64-bit hash register. */
1635 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1636
1637 /* Enable Hashing */
1638 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1639 }
1640
1641 if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
1642 !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
1643
1644 /* Set 64-bit hash register to InexactFilter. */
1645 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
1646 &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
1647
1648 /* Enable Hashing. */
1649 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1650 }
1651
1652 if ((NewPromMode & SK_PROM_MODE_LLC) &&
1653 !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
1654
1655 /* Set the MAC to Promiscuous Mode. */
1656 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
1657 }
1658 else if ((CurPromMode & SK_PROM_MODE_LLC) &&
1659 !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */
1660
1661 /* Clear Promiscuous Mode. */
1662 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
1663 }
1664
1665 return (SK_ADDR_SUCCESS);
1666
1667} /* SkAddrGmacPromiscuousChange */
1668
1669#endif /* YUKON */
1670
1671#ifndef SK_SLIM
1672
1673/******************************************************************************
1674 *
1675 * SkAddrSwap - swap address info
1676 *
1677 * Description:
1678 * This routine swaps address info of two ports.
1679 *
1680 * Context:
1681 * runtime, pageable
1682 * may be called after SK_INIT_IO
1683 *
1684 * Returns:
1685 * SK_ADDR_SUCCESS
1686 * SK_ADDR_ILLEGAL_PORT
1687 */
1688int SkAddrSwap(
1689SK_AC *pAC, /* adapter context */
1690SK_IOC IoC, /* I/O context */
1691SK_U32 FromPortNumber, /* Port1 Index */
1692SK_U32 ToPortNumber) /* Port2 Index */
1693{
1694 int i;
1695 SK_U8 Byte;
1696 SK_MAC_ADDR MacAddr;
1697 SK_U32 DWord;
1698
1699 if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1700 return (SK_ADDR_ILLEGAL_PORT);
1701 }
1702
1703 if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1704 return (SK_ADDR_ILLEGAL_PORT);
1705 }
1706
1707 if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
1708 return (SK_ADDR_ILLEGAL_PORT);
1709 }
1710
1711 /*
1712 * Swap:
1713 * - Exact Match Entries (GEnesis and Yukon)
1714 * Yukon uses first entry for the logical MAC
1715 * address (stored in the second GMAC register).
1716 * - FirstExactMatchRlmt (GEnesis only)
1717 * - NextExactMatchRlmt (GEnesis only)
1718 * - FirstExactMatchDrv (GEnesis only)
1719 * - NextExactMatchDrv (GEnesis only)
1720 * - 64-bit filter (InexactFilter)
1721 * - Promiscuous Mode
1722 * of ports.
1723 */
1724
1725 for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
1726 MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
1727 pAC->Addr.Port[FromPortNumber].Exact[i] =
1728 pAC->Addr.Port[ToPortNumber].Exact[i];
1729 pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
1730 }
1731
1732 for (i = 0; i < 8; i++) {
1733 Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
1734 pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
1735 pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
1736 pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
1737 }
1738
1739 i = pAC->Addr.Port[FromPortNumber].PromMode;
1740 pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
1741 pAC->Addr.Port[ToPortNumber].PromMode = i;
1742
1743 if (pAC->GIni.GIGenesis) {
1744 DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
1745 pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
1746 pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
1747 pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
1748
1749 DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
1750 pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
1751 pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
1752 pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
1753
1754 DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
1755 pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
1756 pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
1757 pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
1758
1759 DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
1760 pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
1761 pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
1762 pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
1763 }
1764
1765 /* CAUTION: Solution works if only ports of one adapter are in use. */
1766 for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
1767 Net->NetNumber].NumPorts; i++) {
1768 if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
1769 Port[i]->PortNumber == ToPortNumber) {
1770 pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
1771 ActivePort = i;
1772 /* 20001207 RA: Was "ToPortNumber;". */
1773 }
1774 }
1775
1776 (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
1777 (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
1778
1779 return (SK_ADDR_SUCCESS);
1780
1781} /* SkAddrSwap */
1782
1783#endif /* !SK_SLIM */
1784
1785#ifdef __cplusplus
1786}
1787#endif /* __cplusplus */
1788
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
deleted file mode 100644
index 37ce03fb8de3..000000000000
--- a/drivers/net/sk98lin/skdim.c
+++ /dev/null
@@ -1,742 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdim.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.5 $
6 * Date: $Date: 2003/11/28 12:55:40 $
7 * Purpose: All functions to maintain interrupt moderation
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage the dynamic interrupt moderation on both
30 * GEnesis and Yukon adapters.
31 *
32 * Include File Hierarchy:
33 *
34 * "skdrv1st.h"
35 * "skdrv2nd.h"
36 *
37 ******************************************************************************/
38
39#ifndef lint
40static const char SysKonnectFileId[] =
41 "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
42#endif
43
44#define __SKADDR_C
45
46#ifdef __cplusplus
47#error C++ is not yet supported.
48extern "C" {
49#endif
50
51/*******************************************************************************
52**
53** Includes
54**
55*******************************************************************************/
56
57#ifndef __INC_SKDRV1ST_H
58#include "h/skdrv1st.h"
59#endif
60
61#ifndef __INC_SKDRV2ND_H
62#include "h/skdrv2nd.h"
63#endif
64
65#include <linux/kernel_stat.h>
66
67/*******************************************************************************
68**
69** Defines
70**
71*******************************************************************************/
72
73/*******************************************************************************
74**
75** Typedefs
76**
77*******************************************************************************/
78
79/*******************************************************************************
80**
81** Local function prototypes
82**
83*******************************************************************************/
84
85static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
86static SK_U64 GetIsrCalls(SK_AC *pAC);
87static SK_BOOL IsIntModEnabled(SK_AC *pAC);
88static void SetCurrIntCtr(SK_AC *pAC);
89static void EnableIntMod(SK_AC *pAC);
90static void DisableIntMod(SK_AC *pAC);
91static void ResizeDimTimerDuration(SK_AC *pAC);
92static void DisplaySelectedModerationType(SK_AC *pAC);
93static void DisplaySelectedModerationMask(SK_AC *pAC);
94static void DisplayDescrRatio(SK_AC *pAC);
95
96/*******************************************************************************
97**
98** Global variables
99**
100*******************************************************************************/
101
102/*******************************************************************************
103**
104** Local variables
105**
106*******************************************************************************/
107
108/*******************************************************************************
109**
110** Global functions
111**
112*******************************************************************************/
113
114/*******************************************************************************
115** Function : SkDimModerate
116** Description : Called in every ISR to check if moderation is to be applied
117** or not for the current number of interrupts
118** Programmer : Ralph Roesler
119** Last Modified: 22-mar-03
120** Returns : void (!)
121** Notes : -
122*******************************************************************************/
123
124void
125SkDimModerate(SK_AC *pAC) {
126 unsigned int CurrSysLoad = 0; /* expressed in percent */
127 unsigned int LoadIncrease = 0; /* expressed in percent */
128 SK_U64 ThresholdInts = 0;
129 SK_U64 IsrCallsPerSec = 0;
130
131#define M_DIMINFO pAC->DynIrqModInfo
132
133 if (!IsIntModEnabled(pAC)) {
134 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
135 CurrSysLoad = GetCurrentSystemLoad(pAC);
136 if (CurrSysLoad > 75) {
137 /*
138 ** More than 75% total system load! Enable the moderation
139 ** to shield the system against too many interrupts.
140 */
141 EnableIntMod(pAC);
142 } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
143 LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
144 if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
145 C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
146 if (CurrSysLoad > 10) {
147 /*
148 ** More than 50% increase with respect to the
149 ** previous load of the system. Most likely this
150 ** is due to our ISR-proc...
151 */
152 EnableIntMod(pAC);
153 }
154 }
155 } else {
156 /*
157 ** Neither too much system load at all nor too much increase
158 ** with respect to the previous system load. Hence, we can leave
159 ** the ISR-handling like it is without enabling moderation.
160 */
161 }
162 M_DIMINFO.PrevSysLoad = CurrSysLoad;
163 }
164 } else {
165 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
166 ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
167 C_INT_MOD_DISABLE_PERCENTAGE) / 100);
168 IsrCallsPerSec = GetIsrCalls(pAC);
169 if (IsrCallsPerSec <= ThresholdInts) {
170 /*
171 ** The number of interrupts within the last second is
172 ** lower than the disable_percentage of the desried
173 ** maxrate. Therefore we can disable the moderation.
174 */
175 DisableIntMod(pAC);
176 M_DIMINFO.MaxModIntsPerSec =
177 (M_DIMINFO.MaxModIntsPerSecUpperLimit +
178 M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
179 } else {
180 /*
181 ** The number of interrupts per sec is the same as expected.
182 ** Evalulate the descriptor-ratio. If it has changed, a resize
183 ** in the moderation timer might be useful
184 */
185 if (M_DIMINFO.AutoSizing) {
186 ResizeDimTimerDuration(pAC);
187 }
188 }
189 }
190 }
191
192 /*
193 ** Some information to the log...
194 */
195 if (M_DIMINFO.DisplayStats) {
196 DisplaySelectedModerationType(pAC);
197 DisplaySelectedModerationMask(pAC);
198 DisplayDescrRatio(pAC);
199 }
200
201 M_DIMINFO.NbrProcessedDescr = 0;
202 SetCurrIntCtr(pAC);
203}
204
205/*******************************************************************************
206** Function : SkDimStartModerationTimer
207** Description : Starts the audit-timer for the dynamic interrupt moderation
208** Programmer : Ralph Roesler
209** Last Modified: 22-mar-03
210** Returns : void (!)
211** Notes : -
212*******************************************************************************/
213
214void
215SkDimStartModerationTimer(SK_AC *pAC) {
216 SK_EVPARA EventParam; /* Event struct for timer event */
217
218 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
219 EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
220 SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
221 SK_DRV_MODERATION_TIMER_LENGTH,
222 SKGE_DRV, SK_DRV_TIMER, EventParam);
223}
224
225/*******************************************************************************
226** Function : SkDimEnableModerationIfNeeded
227** Description : Either enables or disables moderation
228** Programmer : Ralph Roesler
229** Last Modified: 22-mar-03
230** Returns : void (!)
231** Notes : This function is called when a particular adapter is opened
232** There is no Disable function, because when all interrupts
233** might be disable, the moderation timer has no meaning at all
234******************************************************************************/
235
236void
237SkDimEnableModerationIfNeeded(SK_AC *pAC) {
238
239 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
240 EnableIntMod(pAC); /* notification print in this function */
241 } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
242 SkDimStartModerationTimer(pAC);
243 if (M_DIMINFO.DisplayStats) {
244 printk("Dynamic moderation has been enabled\n");
245 }
246 } else {
247 if (M_DIMINFO.DisplayStats) {
248 printk("No moderation has been enabled\n");
249 }
250 }
251}
252
253/*******************************************************************************
254** Function : SkDimDisplayModerationSettings
255** Description : Displays the current settings regarding interrupt moderation
256** Programmer : Ralph Roesler
257** Last Modified: 22-mar-03
258** Returns : void (!)
259** Notes : -
260*******************************************************************************/
261
262void
263SkDimDisplayModerationSettings(SK_AC *pAC) {
264 DisplaySelectedModerationType(pAC);
265 DisplaySelectedModerationMask(pAC);
266}
267
268/*******************************************************************************
269**
270** Local functions
271**
272*******************************************************************************/
273
274/*******************************************************************************
275** Function : GetCurrentSystemLoad
276** Description : Retrieves the current system load of the system. This load
277** is evaluated for all processors within the system.
278** Programmer : Ralph Roesler
279** Last Modified: 22-mar-03
280** Returns : unsigned int: load expressed in percentage
281** Notes : The possible range being returned is from 0 up to 100.
282** Whereas 0 means 'no load at all' and 100 'system fully loaded'
283** It is impossible to determine what actually causes the system
284** to be in 100%, but maybe that is due to too much interrupts.
285*******************************************************************************/
286
287static unsigned int
288GetCurrentSystemLoad(SK_AC *pAC) {
289 unsigned long jif = jiffies;
290 unsigned int UserTime = 0;
291 unsigned int SystemTime = 0;
292 unsigned int NiceTime = 0;
293 unsigned int IdleTime = 0;
294 unsigned int TotalTime = 0;
295 unsigned int UsedTime = 0;
296 unsigned int SystemLoad = 0;
297
298 /* unsigned int NbrCpu = 0; */
299
300 /*
301 ** The following lines have been commented out, because
302 ** from kernel 2.5.44 onwards, the kernel-owned structure
303 **
304 ** struct kernel_stat kstat
305 **
306 ** is not marked as an exported symbol in the file
307 **
308 ** kernel/ksyms.c
309 **
310 ** As a consequence, using this driver as KLM is not possible
311 ** and any access of the structure kernel_stat via the
312 ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
313 **
314 ** The kstat-information might be added again in future
315 ** versions of the 2.5.xx kernel, but for the time being,
316 ** number of interrupts will serve as indication how much
317 ** load we currently have...
318 **
319 ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
320 ** UserTime = UserTime + kstat_cpu(NbrCpu).cpustat.user;
321 ** NiceTime = NiceTime + kstat_cpu(NbrCpu).cpustat.nice;
322 ** SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
323 ** }
324 */
325 SK_U64 ThresholdInts = 0;
326 SK_U64 IsrCallsPerSec = 0;
327
328 ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
329 C_INT_MOD_ENABLE_PERCENTAGE) + 100);
330 IsrCallsPerSec = GetIsrCalls(pAC);
331 if (IsrCallsPerSec >= ThresholdInts) {
332 /*
333 ** We do not know how much the real CPU-load is!
334 ** Return 80% as a default in order to activate DIM
335 */
336 SystemLoad = 80;
337 return (SystemLoad);
338 }
339
340 UsedTime = UserTime + NiceTime + SystemTime;
341
342 IdleTime = jif * num_online_cpus() - UsedTime;
343 TotalTime = UsedTime + IdleTime;
344
345 SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) /
346 (TotalTime - M_DIMINFO.PrevTotalTime);
347
348 if (M_DIMINFO.DisplayStats) {
349 printk("Current system load is: %u\n", SystemLoad);
350 }
351
352 M_DIMINFO.PrevTotalTime = TotalTime;
353 M_DIMINFO.PrevUsedTime = UsedTime;
354
355 return (SystemLoad);
356}
357
358/*******************************************************************************
359** Function : GetIsrCalls
360** Description : Depending on the selected moderation mask, this function will
361** return the number of interrupts handled in the previous time-
362** frame. This evaluated number is based on the current number
363** of interrupts stored in PNMI-context and the previous stored
364** interrupts.
365** Programmer : Ralph Roesler
366** Last Modified: 23-mar-03
367** Returns : int: the number of interrupts being executed in the last
368** timeframe
369** Notes : It makes only sense to call this function, when dynamic
370** interrupt moderation is applied
371*******************************************************************************/
372
373static SK_U64
374GetIsrCalls(SK_AC *pAC) {
375 SK_U64 RxPort0IntDiff = 0;
376 SK_U64 RxPort1IntDiff = 0;
377 SK_U64 TxPort0IntDiff = 0;
378 SK_U64 TxPort1IntDiff = 0;
379
380 if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
381 if (pAC->GIni.GIMacsFound == 2) {
382 TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
383 pAC->DynIrqModInfo.PrevPort1TxIntrCts;
384 }
385 TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
386 pAC->DynIrqModInfo.PrevPort0TxIntrCts;
387 } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
388 if (pAC->GIni.GIMacsFound == 2) {
389 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
390 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
391 }
392 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
393 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
394 } else {
395 if (pAC->GIni.GIMacsFound == 2) {
396 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
397 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
398 TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
399 pAC->DynIrqModInfo.PrevPort1TxIntrCts;
400 }
401 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
402 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
403 TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
404 pAC->DynIrqModInfo.PrevPort0TxIntrCts;
405 }
406
407 return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
408}
409
410/*******************************************************************************
411** Function : GetRxCalls
412** Description : This function will return the number of times a receive inter-
413** rupt was processed. This is needed to evaluate any resizing
414** factor.
415** Programmer : Ralph Roesler
416** Last Modified: 23-mar-03
417** Returns : SK_U64: the number of RX-ints being processed
418** Notes : It makes only sense to call this function, when dynamic
419** interrupt moderation is applied
420*******************************************************************************/
421
422static SK_U64
423GetRxCalls(SK_AC *pAC) {
424 SK_U64 RxPort0IntDiff = 0;
425 SK_U64 RxPort1IntDiff = 0;
426
427 if (pAC->GIni.GIMacsFound == 2) {
428 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
429 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
430 }
431 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
432 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
433
434 return (RxPort0IntDiff + RxPort1IntDiff);
435}
436
437/*******************************************************************************
438** Function : SetCurrIntCtr
439** Description : Will store the current number orf occured interrupts in the
440** adapter context. This is needed to evaluated the number of
441** interrupts within a current timeframe.
442** Programmer : Ralph Roesler
443** Last Modified: 23-mar-03
444** Returns : void (!)
445** Notes : -
446*******************************************************************************/
447
448static void
449SetCurrIntCtr(SK_AC *pAC) {
450 if (pAC->GIni.GIMacsFound == 2) {
451 pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
452 pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
453 }
454 pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
455 pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
456}
457
458/*******************************************************************************
459** Function : IsIntModEnabled()
460** Description : Retrieves the current value of the interrupts moderation
461** command register. Its content determines whether any
462** moderation is running or not.
463** Programmer : Ralph Roesler
464** Last Modified: 23-mar-03
465** Returns : SK_TRUE : if mod timer running
466** SK_FALSE : if no moderation is being performed
467** Notes : -
468*******************************************************************************/
469
470static SK_BOOL
471IsIntModEnabled(SK_AC *pAC) {
472 unsigned long CtrCmd;
473
474 SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
475 if ((CtrCmd & TIM_START) == TIM_START) {
476 return SK_TRUE;
477 } else {
478 return SK_FALSE;
479 }
480}
481
482/*******************************************************************************
483** Function : EnableIntMod()
484** Description : Enables the interrupt moderation using the values stored in
485** in the pAC->DynIntMod data structure
486** Programmer : Ralph Roesler
487** Last Modified: 22-mar-03
488** Returns : -
489** Notes : -
490*******************************************************************************/
491
492static void
493EnableIntMod(SK_AC *pAC) {
494 unsigned long ModBase;
495
496 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
497 ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
498 } else {
499 ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
500 }
501
502 SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
503 SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration);
504 SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
505 if (M_DIMINFO.DisplayStats) {
506 printk("Enabled interrupt moderation (%i ints/sec)\n",
507 M_DIMINFO.MaxModIntsPerSec);
508 }
509}
510
511/*******************************************************************************
512** Function : DisableIntMod()
513** Description : Disables the interrupt moderation independent of what inter-
514** rupts are running or not
515** Programmer : Ralph Roesler
516** Last Modified: 23-mar-03
517** Returns : -
518** Notes : -
519*******************************************************************************/
520
521static void
522DisableIntMod(SK_AC *pAC) {
523
524 SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
525 if (M_DIMINFO.DisplayStats) {
526 printk("Disabled interrupt moderation\n");
527 }
528}
529
530/*******************************************************************************
531** Function : ResizeDimTimerDuration();
532** Description : Checks the current used descriptor ratio and resizes the
533** duration timer (longer/smaller) if possible.
534** Programmer : Ralph Roesler
535** Last Modified: 23-mar-03
536** Returns : -
537** Notes : There are both maximum and minimum timer duration value.
538** This function assumes that interrupt moderation is already
539** enabled!
540*******************************************************************************/
541
542static void
543ResizeDimTimerDuration(SK_AC *pAC) {
544 SK_BOOL IncreaseTimerDuration;
545 int TotalMaxNbrDescr;
546 int UsedDescrRatio;
547 int RatioDiffAbs;
548 int RatioDiffRel;
549 int NewMaxModIntsPerSec;
550 int ModAdjValue;
551 long ModBase;
552
553 /*
554 ** Check first if we are allowed to perform any modification
555 */
556 if (IsIntModEnabled(pAC)) {
557 if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
558 return;
559 } else {
560 if (M_DIMINFO.ModJustEnabled) {
561 M_DIMINFO.ModJustEnabled = SK_FALSE;
562 return;
563 }
564 }
565 }
566
567 /*
568 ** If we got until here, we have to evaluate the amount of the
569 ** descriptor ratio change...
570 */
571 TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
572 UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
573
574 if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
575 RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
576 RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
577 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
578 IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */
579 } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
580 RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
581 RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
582 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
583 IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
584 } else {
585 RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
586 RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
587 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
588 IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
589 }
590
591 /*
592 ** Now we can determine the change in percent
593 */
594 if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
595 ModAdjValue = 1; /* 1% change - maybe some other value in future */
596 } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
597 ModAdjValue = 1; /* 1% change - maybe some other value in future */
598 } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
599 ModAdjValue = 1; /* 1% change - maybe some other value in future */
600 } else {
601 ModAdjValue = 1; /* 1% change - maybe some other value in future */
602 }
603
604 if (IncreaseTimerDuration) {
605 NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec +
606 (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
607 } else {
608 NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec -
609 (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
610 }
611
612 /*
613 ** Check if we exceed boundaries...
614 */
615 if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
616 (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
617 if (M_DIMINFO.DisplayStats) {
618 printk("Cannot change ModTim from %i to %i ints/sec\n",
619 M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
620 }
621 return;
622 } else {
623 if (M_DIMINFO.DisplayStats) {
624 printk("Resized ModTim from %i to %i ints/sec\n",
625 M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
626 }
627 }
628
629 M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
630
631 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
632 ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
633 } else {
634 ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
635 }
636
637 /*
638 ** We do not need to touch any other registers
639 */
640 SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
641}
642
643/*******************************************************************************
644** Function : DisplaySelectedModerationType()
645** Description : Displays what type of moderation we have
646** Programmer : Ralph Roesler
647** Last Modified: 23-mar-03
648** Returns : void!
649** Notes : -
650*******************************************************************************/
651
652static void
653DisplaySelectedModerationType(SK_AC *pAC) {
654
655 if (pAC->DynIrqModInfo.DisplayStats) {
656 if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
657 printk("Static int moderation runs with %i INTS/sec\n",
658 pAC->DynIrqModInfo.MaxModIntsPerSec);
659 } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
660 if (IsIntModEnabled(pAC)) {
661 printk("Dynamic int moderation runs with %i INTS/sec\n",
662 pAC->DynIrqModInfo.MaxModIntsPerSec);
663 } else {
664 printk("Dynamic int moderation currently not applied\n");
665 }
666 } else {
667 printk("No interrupt moderation selected!\n");
668 }
669 }
670}
671
672/*******************************************************************************
673** Function : DisplaySelectedModerationMask()
674** Description : Displays what interrupts are moderated
675** Programmer : Ralph Roesler
676** Last Modified: 23-mar-03
677** Returns : void!
678** Notes : -
679*******************************************************************************/
680
681static void
682DisplaySelectedModerationMask(SK_AC *pAC) {
683
684 if (pAC->DynIrqModInfo.DisplayStats) {
685 if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
686 switch (pAC->DynIrqModInfo.MaskIrqModeration) {
687 case IRQ_MASK_TX_ONLY:
688 printk("Only Tx-interrupts are moderated\n");
689 break;
690 case IRQ_MASK_RX_ONLY:
691 printk("Only Rx-interrupts are moderated\n");
692 break;
693 case IRQ_MASK_SP_ONLY:
694 printk("Only special-interrupts are moderated\n");
695 break;
696 case IRQ_MASK_TX_RX:
697 printk("Tx- and Rx-interrupts are moderated\n");
698 break;
699 case IRQ_MASK_SP_RX:
700 printk("Special- and Rx-interrupts are moderated\n");
701 break;
702 case IRQ_MASK_SP_TX:
703 printk("Special- and Tx-interrupts are moderated\n");
704 break;
705 case IRQ_MASK_RX_TX_SP:
706 printk("All Rx-, Tx and special-interrupts are moderated\n");
707 break;
708 default:
709 printk("Don't know what is moderated\n");
710 break;
711 }
712 } else {
713 printk("No specific interrupts masked for moderation\n");
714 }
715 }
716}
717
718/*******************************************************************************
719** Function : DisplayDescrRatio
720** Description : Like the name states...
721** Programmer : Ralph Roesler
722** Last Modified: 23-mar-03
723** Returns : void!
724** Notes : -
725*******************************************************************************/
726
727static void
728DisplayDescrRatio(SK_AC *pAC) {
729 int TotalMaxNbrDescr = 0;
730
731 if (pAC->DynIrqModInfo.DisplayStats) {
732 TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
733 printk("Ratio descriptors: %i/%i\n",
734 M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
735 }
736}
737
738/*******************************************************************************
739**
740** End of file
741**
742*******************************************************************************/
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
deleted file mode 100644
index 5a6da8950faa..000000000000
--- a/drivers/net/sk98lin/skethtool.c
+++ /dev/null
@@ -1,627 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skethtool.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2004/09/29 13:32:07 $
7 * Purpose: All functions regarding ethtool handling
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2004 Marvell.
15 *
16 * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet
17 * Server Adapters.
18 *
19 * Author: Ralph Roesler (rroesler@syskonnect.de)
20 * Mirko Lindner (mlindner@syskonnect.de)
21 *
22 * Address all question to: linux@syskonnect.de
23 *
24 * The technical manual for the adapters is available from SysKonnect's
25 * web pages: www.syskonnect.com
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * The information in this file is provided "AS IS" without warranty.
33 *
34 *****************************************************************************/
35
36#include "h/skdrv1st.h"
37#include "h/skdrv2nd.h"
38#include "h/skversion.h"
39
40#include <linux/ethtool.h>
41#include <linux/timer.h>
42#include <linux/delay.h>
43
44/******************************************************************************
45 *
46 * Defines
47 *
48 *****************************************************************************/
49
50#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
51 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
52 SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
53 SUPPORTED_TP)
54
55#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
56 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
57 ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
58 ADVERTISED_TP)
59
60#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \
61 SUPPORTED_FIBRE | \
62 SUPPORTED_Autoneg)
63
64#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \
65 ADVERTISED_FIBRE | \
66 ADVERTISED_Autoneg)
67
68
69/******************************************************************************
70 *
71 * Local Functions
72 *
73 *****************************************************************************/
74
75/*****************************************************************************
76 *
77 * getSettings - retrieves the current settings of the selected adapter
78 *
79 * Description:
80 * The current configuration of the selected adapter is returned.
81 * This configuration involves a)speed, b)duplex and c)autoneg plus
82 * a number of other variables.
83 *
84 * Returns: always 0
85 *
86 */
87static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
88{
89 const DEV_NET *pNet = netdev_priv(dev);
90 int port = pNet->PortNr;
91 const SK_AC *pAC = pNet->pAC;
92 const SK_GEPORT *pPort = &pAC->GIni.GP[port];
93
94 static int DuplexAutoNegConfMap[9][3]= {
95 { -1 , -1 , -1 },
96 { 0 , -1 , -1 },
97 { SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE },
98 { SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE },
99 { SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE },
100 { SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE },
101 { SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE },
102 { SK_LMODE_AUTOSENSE , -1 , -1 },
103 { SK_LMODE_INDETERMINATED, -1 , -1 }
104 };
105 static int SpeedConfMap[6][2] = {
106 { 0 , -1 },
107 { SK_LSPEED_AUTO , -1 },
108 { SK_LSPEED_10MBPS , SPEED_10 },
109 { SK_LSPEED_100MBPS , SPEED_100 },
110 { SK_LSPEED_1000MBPS , SPEED_1000 },
111 { SK_LSPEED_INDETERMINATED, -1 }
112 };
113 static int AdvSpeedMap[6][2] = {
114 { 0 , -1 },
115 { SK_LSPEED_AUTO , -1 },
116 { SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full },
117 { SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full },
118 { SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
119 { SK_LSPEED_INDETERMINATED, -1 }
120 };
121
122 ecmd->phy_address = port;
123 ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1];
124 ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
125 ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
126 ecmd->transceiver = XCVR_INTERNAL;
127
128 if (pAC->GIni.GICopperType) {
129 ecmd->port = PORT_TP;
130 ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
131 if (pAC->GIni.GIGenesis) {
132 ecmd->supported &= ~(SUPPORTED_10baseT_Half);
133 ecmd->supported &= ~(SUPPORTED_10baseT_Full);
134 ecmd->supported &= ~(SUPPORTED_100baseT_Half);
135 ecmd->supported &= ~(SUPPORTED_100baseT_Full);
136 } else {
137 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
138 ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
139 }
140#ifdef CHIP_ID_YUKON_FE
141 if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
142 ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
143 ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
144 }
145#endif
146 }
147 if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
148 ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
149 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
150 ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
151 }
152 } else {
153 ecmd->advertising = ecmd->supported;
154 }
155
156 if (ecmd->autoneg == AUTONEG_ENABLE)
157 ecmd->advertising |= ADVERTISED_Autoneg;
158 } else {
159 ecmd->port = PORT_FIBRE;
160 ecmd->supported = SUPP_FIBRE_ALL;
161 ecmd->advertising = ADV_FIBRE_ALL;
162 }
163 return 0;
164}
165
166/*
167 * MIB infrastructure uses instance value starting at 1
168 * based on board and port.
169 */
170static inline u32 pnmiInstance(const DEV_NET *pNet)
171{
172 return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
173}
174
175/*****************************************************************************
176 *
177 * setSettings - configures the settings of a selected adapter
178 *
179 * Description:
180 * Possible settings that may be altered are a)speed, b)duplex or
181 * c)autonegotiation.
182 *
183 * Returns:
184 * 0: everything fine, no error
185 * <0: the return value is the error code of the failure
186 */
187static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
188{
189 DEV_NET *pNet = netdev_priv(dev);
190 SK_AC *pAC = pNet->pAC;
191 u32 instance;
192 char buf[4];
193 int len = 1;
194
195 if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100
196 && ecmd->speed != SPEED_1000)
197 return -EINVAL;
198
199 if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
200 return -EINVAL;
201
202 if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
203 return -EINVAL;
204
205 if (ecmd->autoneg == AUTONEG_DISABLE)
206 *buf = (ecmd->duplex == DUPLEX_FULL)
207 ? SK_LMODE_FULL : SK_LMODE_HALF;
208 else
209 *buf = (ecmd->duplex == DUPLEX_FULL)
210 ? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
211
212 instance = pnmiInstance(pNet);
213 if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE,
214 &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
215 return -EINVAL;
216
217 switch(ecmd->speed) {
218 case SPEED_1000:
219 *buf = SK_LSPEED_1000MBPS;
220 break;
221 case SPEED_100:
222 *buf = SK_LSPEED_100MBPS;
223 break;
224 case SPEED_10:
225 *buf = SK_LSPEED_10MBPS;
226 }
227
228 if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
229 &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
230 return -EINVAL;
231
232 return 0;
233}
234
235/*****************************************************************************
236 *
237 * getDriverInfo - returns generic driver and adapter information
238 *
239 * Description:
240 * Generic driver information is returned via this function, such as
241 * the name of the driver, its version and and firmware version.
242 * In addition to this, the location of the selected adapter is
243 * returned as a bus info string (e.g. '01:05.0').
244 *
245 * Returns: N/A
246 *
247 */
248static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
249{
250 const DEV_NET *pNet = netdev_priv(dev);
251 const SK_AC *pAC = pNet->pAC;
252 char vers[32];
253
254 snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
255 (pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
256
257 strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
258 strcpy(info->version, vers);
259 strcpy(info->fw_version, "N/A");
260 strlcpy(info->bus_info, pci_name(pAC->PciDev), ETHTOOL_BUSINFO_LEN);
261}
262
263/*
264 * Ethtool statistics support.
265 */
266static const char StringsStats[][ETH_GSTRING_LEN] = {
267 "rx_packets", "tx_packets",
268 "rx_bytes", "tx_bytes",
269 "rx_errors", "tx_errors",
270 "rx_dropped", "tx_dropped",
271 "multicasts", "collisions",
272 "rx_length_errors", "rx_buffer_overflow_errors",
273 "rx_crc_errors", "rx_frame_errors",
274 "rx_too_short_errors", "rx_too_long_errors",
275 "rx_carrier_extension_errors", "rx_symbol_errors",
276 "rx_llc_mac_size_errors", "rx_carrier_errors",
277 "rx_jabber_errors", "rx_missed_errors",
278 "tx_abort_collision_errors", "tx_carrier_errors",
279 "tx_buffer_underrun_errors", "tx_heartbeat_errors",
280 "tx_window_errors",
281};
282
283static int getStatsCount(struct net_device *dev)
284{
285 return ARRAY_SIZE(StringsStats);
286}
287
288static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
289{
290 switch(stringset) {
291 case ETH_SS_STATS:
292 memcpy(data, *StringsStats, sizeof(StringsStats));
293 break;
294 }
295}
296
297static void getEthtoolStats(struct net_device *dev,
298 struct ethtool_stats *stats, u64 *data)
299{
300 const DEV_NET *pNet = netdev_priv(dev);
301 const SK_AC *pAC = pNet->pAC;
302 const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
303
304 *data++ = pPnmiStruct->Stat[0].StatRxOkCts;
305 *data++ = pPnmiStruct->Stat[0].StatTxOkCts;
306 *data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
307 *data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
308 *data++ = pPnmiStruct->InErrorsCts;
309 *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
310 *data++ = pPnmiStruct->RxNoBufCts;
311 *data++ = pPnmiStruct->TxNoBufCts;
312 *data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
313 *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
314 *data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
315 *data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
316 *data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
317 *data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
318 *data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
319 *data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
320 *data++ = pPnmiStruct->Stat[0].StatRxCextCts;
321 *data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
322 *data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
323 *data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
324 *data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
325 *data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
326 *data++ = pAC->stats.tx_aborted_errors;
327 *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
328 *data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
329 *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
330 *data++ = pAC->stats.tx_window_errors;
331}
332
333
334/*****************************************************************************
335 *
336 * toggleLeds - Changes the LED state of an adapter
337 *
338 * Description:
339 * This function changes the current state of all LEDs of an adapter so
340 * that it can be located by a user.
341 *
342 * Returns: N/A
343 *
344 */
345static void toggleLeds(DEV_NET *pNet, int on)
346{
347 SK_AC *pAC = pNet->pAC;
348 int port = pNet->PortNr;
349 void __iomem *io = pAC->IoBase;
350
351 if (pAC->GIni.GIGenesis) {
352 SK_OUT8(io, MR_ADDR(port,LNK_LED_REG),
353 on ? SK_LNK_ON : SK_LNK_OFF);
354 SkGeYellowLED(pAC, io,
355 on ? (LED_ON >> 1) : (LED_OFF >> 1));
356 SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
357 on ? SK_LED_TST : SK_LED_DIS);
358
359 if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
360 SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL,
361 on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
362 else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
363 SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
364 on ? 0x0800 : PHY_L_LC_LEDT);
365 else
366 SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
367 on ? SK_LED_TST : SK_LED_DIS);
368 } else {
369 const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) |
370 PHY_M_LED_MO_10(MO_LED_ON) |
371 PHY_M_LED_MO_100(MO_LED_ON) |
372 PHY_M_LED_MO_1000(MO_LED_ON) |
373 PHY_M_LED_MO_RX(MO_LED_ON));
374 const u16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) |
375 PHY_M_LED_MO_10(MO_LED_OFF) |
376 PHY_M_LED_MO_100(MO_LED_OFF) |
377 PHY_M_LED_MO_1000(MO_LED_OFF) |
378 PHY_M_LED_MO_RX(MO_LED_OFF));
379
380
381 SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
382 SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER,
383 on ? YukLedOn : YukLedOff);
384 }
385}
386
387/*****************************************************************************
388 *
389 * skGeBlinkTimer - Changes the LED state of an adapter
390 *
391 * Description:
392 * This function changes the current state of all LEDs of an adapter so
393 * that it can be located by a user. If the requested time interval for
394 * this test has elapsed, this function cleans up everything that was
395 * temporarily setup during the locate NIC test. This involves of course
396 * also closing or opening any adapter so that the initial board state
397 * is recovered.
398 *
399 * Returns: N/A
400 *
401 */
402void SkGeBlinkTimer(unsigned long data)
403{
404 struct net_device *dev = (struct net_device *) data;
405 DEV_NET *pNet = netdev_priv(dev);
406 SK_AC *pAC = pNet->pAC;
407
408 toggleLeds(pNet, pAC->LedsOn);
409
410 pAC->LedsOn = !pAC->LedsOn;
411 mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
412}
413
414/*****************************************************************************
415 *
416 * locateDevice - start the locate NIC feature of the elected adapter
417 *
418 * Description:
419 * This function is used if the user want to locate a particular NIC.
420 * All LEDs are regularly switched on and off, so the NIC can easily
421 * be identified.
422 *
423 * Returns:
424 * ==0: everything fine, no error, locateNIC test was started
425 * !=0: one locateNIC test runs already
426 *
427 */
428static int locateDevice(struct net_device *dev, u32 data)
429{
430 DEV_NET *pNet = netdev_priv(dev);
431 SK_AC *pAC = pNet->pAC;
432
433 if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
434 data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
435
436 /* start blinking */
437 pAC->LedsOn = 0;
438 mod_timer(&pAC->BlinkTimer, jiffies);
439 msleep_interruptible(data * 1000);
440 del_timer_sync(&pAC->BlinkTimer);
441 toggleLeds(pNet, 0);
442
443 return 0;
444}
445
446/*****************************************************************************
447 *
448 * getPauseParams - retrieves the pause parameters
449 *
450 * Description:
451 * All current pause parameters of a selected adapter are placed
452 * in the passed ethtool_pauseparam structure and are returned.
453 *
454 * Returns: N/A
455 *
456 */
457static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause)
458{
459 DEV_NET *pNet = netdev_priv(dev);
460 SK_AC *pAC = pNet->pAC;
461 SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
462
463 epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
464 (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
465
466 epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
467 epause->autoneg = epause->rx_pause || epause->tx_pause;
468}
469
470/*****************************************************************************
471 *
472 * setPauseParams - configures the pause parameters of an adapter
473 *
474 * Description:
475 * This function sets the Rx or Tx pause parameters
476 *
477 * Returns:
478 * ==0: everything fine, no error
479 * !=0: the return value is the error code of the failure
480 */
481static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
482{
483 DEV_NET *pNet = netdev_priv(dev);
484 SK_AC *pAC = pNet->pAC;
485 SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
486 u32 instance = pnmiInstance(pNet);
487 struct ethtool_pauseparam old;
488 u8 oldspeed = pPort->PLinkSpeedUsed;
489 char buf[4];
490 int len = 1;
491 int ret;
492
493 /*
494 ** we have to determine the current settings to see if
495 ** the operator requested any modification of the flow
496 ** control parameters...
497 */
498 getPauseParams(dev, &old);
499
500 /*
501 ** perform modifications regarding the changes
502 ** requested by the operator
503 */
504 if (epause->autoneg != old.autoneg)
505 *buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
506 else {
507 if (epause->rx_pause && epause->tx_pause)
508 *buf = SK_FLOW_MODE_SYMMETRIC;
509 else if (epause->rx_pause && !epause->tx_pause)
510 *buf = SK_FLOW_MODE_SYM_OR_REM;
511 else if (!epause->rx_pause && epause->tx_pause)
512 *buf = SK_FLOW_MODE_LOC_SEND;
513 else
514 *buf = SK_FLOW_MODE_NONE;
515 }
516
517 ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
518 &buf, &len, instance, pNet->NetNr);
519
520 if (ret != SK_PNMI_ERR_OK) {
521 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
522 ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
523 goto err;
524 }
525
526 /*
527 ** It may be that autoneg has been disabled! Therefore
528 ** set the speed to the previously used value...
529 */
530 if (!epause->autoneg) {
531 len = 1;
532 ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
533 &oldspeed, &len, instance, pNet->NetNr);
534 if (ret != SK_PNMI_ERR_OK)
535 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
536 ("ethtool (sk98lin): error setting speed (%i)\n", ret));
537 }
538 err:
539 return ret ? -EIO : 0;
540}
541
542/* Only Yukon supports checksum offload. */
543static int setScatterGather(struct net_device *dev, u32 data)
544{
545 DEV_NET *pNet = netdev_priv(dev);
546 SK_AC *pAC = pNet->pAC;
547
548 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
549 return -EOPNOTSUPP;
550 return ethtool_op_set_sg(dev, data);
551}
552
553static int setTxCsum(struct net_device *dev, u32 data)
554{
555 DEV_NET *pNet = netdev_priv(dev);
556 SK_AC *pAC = pNet->pAC;
557
558 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
559 return -EOPNOTSUPP;
560
561 return ethtool_op_set_tx_csum(dev, data);
562}
563
564static u32 getRxCsum(struct net_device *dev)
565{
566 DEV_NET *pNet = netdev_priv(dev);
567 SK_AC *pAC = pNet->pAC;
568
569 return pAC->RxPort[pNet->PortNr].RxCsum;
570}
571
572static int setRxCsum(struct net_device *dev, u32 data)
573{
574 DEV_NET *pNet = netdev_priv(dev);
575 SK_AC *pAC = pNet->pAC;
576
577 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
578 return -EOPNOTSUPP;
579
580 pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
581 return 0;
582}
583
584static int getRegsLen(struct net_device *dev)
585{
586 return 0x4000;
587}
588
589/*
590 * Returns copy of whole control register region
591 * Note: skip RAM address register because accessing it will
592 * cause bus hangs!
593 */
594static void getRegs(struct net_device *dev, struct ethtool_regs *regs,
595 void *p)
596{
597 DEV_NET *pNet = netdev_priv(dev);
598 const void __iomem *io = pNet->pAC->IoBase;
599
600 regs->version = 1;
601 memset(p, 0, regs->len);
602 memcpy_fromio(p, io, B3_RAM_ADDR);
603
604 memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1,
605 regs->len - B3_RI_WTO_R1);
606}
607
608const struct ethtool_ops SkGeEthtoolOps = {
609 .get_settings = getSettings,
610 .set_settings = setSettings,
611 .get_drvinfo = getDriverInfo,
612 .get_strings = getStrings,
613 .get_stats_count = getStatsCount,
614 .get_ethtool_stats = getEthtoolStats,
615 .phys_id = locateDevice,
616 .get_pauseparam = getPauseParams,
617 .set_pauseparam = setPauseParams,
618 .get_link = ethtool_op_get_link,
619 .get_sg = ethtool_op_get_sg,
620 .set_sg = setScatterGather,
621 .get_tx_csum = ethtool_op_get_tx_csum,
622 .set_tx_csum = setTxCsum,
623 .get_rx_csum = getRxCsum,
624 .set_rx_csum = setRxCsum,
625 .get_regs = getRegs,
626 .get_regs_len = getRegsLen,
627};
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
deleted file mode 100644
index 20890e44f99a..000000000000
--- a/drivers/net/sk98lin/skge.c
+++ /dev/null
@@ -1,5218 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skge.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.45 $
6 * Date: $Date: 2004/02/12 14:41:02 $
7 * Purpose: The main driver source module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet
17 * Server Adapters.
18 *
19 * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
20 * SysKonnects GEnesis Solaris driver
21 * Author: Christoph Goos (cgoos@syskonnect.de)
22 * Mirko Lindner (mlindner@syskonnect.de)
23 *
24 * Address all question to: linux@syskonnect.de
25 *
26 * The technical manual for the adapters is available from SysKonnect's
27 * web pages: www.syskonnect.com
28 * Goto "Support" and search Knowledge Base for "manual".
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * The information in this file is provided "AS IS" without warranty.
36 *
37 ******************************************************************************/
38
39/******************************************************************************
40 *
41 * Possible compiler options (#define xxx / -Dxxx):
42 *
43 * debugging can be enable by changing SK_DEBUG_CHKMOD and
44 * SK_DEBUG_CHKCAT in makefile (described there).
45 *
46 ******************************************************************************/
47
48/******************************************************************************
49 *
50 * Description:
51 *
52 * This is the main module of the Linux GE driver.
53 *
54 * All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
55 * are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
56 * Those are used for drivers on multiple OS', so some thing may seem
57 * unnecessary complicated on Linux. Please do not try to 'clean up'
58 * them without VERY good reasons, because this will make it more
59 * difficult to keep the Linux driver in synchronisation with the
60 * other versions.
61 *
62 * Include file hierarchy:
63 *
64 * <linux/module.h>
65 *
66 * "h/skdrv1st.h"
67 * <linux/types.h>
68 * <linux/kernel.h>
69 * <linux/string.h>
70 * <linux/errno.h>
71 * <linux/ioport.h>
72 * <linux/slab.h>
73 * <linux/interrupt.h>
74 * <linux/pci.h>
75 * <linux/bitops.h>
76 * <asm/byteorder.h>
77 * <asm/io.h>
78 * <linux/netdevice.h>
79 * <linux/etherdevice.h>
80 * <linux/skbuff.h>
81 * those three depending on kernel version used:
82 * <linux/bios32.h>
83 * <linux/init.h>
84 * <asm/uaccess.h>
85 * <net/checksum.h>
86 *
87 * "h/skerror.h"
88 * "h/skdebug.h"
89 * "h/sktypes.h"
90 * "h/lm80.h"
91 * "h/xmac_ii.h"
92 *
93 * "h/skdrv2nd.h"
94 * "h/skqueue.h"
95 * "h/skgehwt.h"
96 * "h/sktimer.h"
97 * "h/ski2c.h"
98 * "h/skgepnmi.h"
99 * "h/skvpd.h"
100 * "h/skgehw.h"
101 * "h/skgeinit.h"
102 * "h/skaddr.h"
103 * "h/skgesirq.h"
104 * "h/skrlmt.h"
105 *
106 ******************************************************************************/
107
108#include "h/skversion.h"
109
110#include <linux/in.h>
111#include <linux/module.h>
112#include <linux/moduleparam.h>
113#include <linux/init.h>
114#include <linux/dma-mapping.h>
115#include <linux/ip.h>
116#include <linux/mii.h>
117#include <linux/mm.h>
118
119#include "h/skdrv1st.h"
120#include "h/skdrv2nd.h"
121
122/*******************************************************************************
123 *
124 * Defines
125 *
126 ******************************************************************************/
127
128/* for debuging on x86 only */
129/* #define BREAKPOINT() asm(" int $3"); */
130
131/* use the transmit hw checksum driver functionality */
132#define USE_SK_TX_CHECKSUM
133
134/* use the receive hw checksum driver functionality */
135#define USE_SK_RX_CHECKSUM
136
137/* use the scatter-gather functionality with sendfile() */
138#define SK_ZEROCOPY
139
140/* use of a transmit complete interrupt */
141#define USE_TX_COMPLETE
142
143/*
144 * threshold for copying small receive frames
145 * set to 0 to avoid copying, set to 9001 to copy all frames
146 */
147#define SK_COPY_THRESHOLD 50
148
149/* number of adapters that can be configured via command line params */
150#define SK_MAX_CARD_PARAM 16
151
152
153
154/*
155 * use those defines for a compile-in version of the driver instead
156 * of command line parameters
157 */
158// #define LINK_SPEED_A {"Auto", }
159// #define LINK_SPEED_B {"Auto", }
160// #define AUTO_NEG_A {"Sense", }
161// #define AUTO_NEG_B {"Sense", }
162// #define DUP_CAP_A {"Both", }
163// #define DUP_CAP_B {"Both", }
164// #define FLOW_CTRL_A {"SymOrRem", }
165// #define FLOW_CTRL_B {"SymOrRem", }
166// #define ROLE_A {"Auto", }
167// #define ROLE_B {"Auto", }
168// #define PREF_PORT {"A", }
169// #define CON_TYPE {"Auto", }
170// #define RLMT_MODE {"CheckLinkState", }
171
172#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
173#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
174#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
175
176
177/* Set blink mode*/
178#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \
179 SK_DUP_LED_NORMAL | \
180 SK_LED_LINK100_ON)
181
182
183/* Isr return value */
184#define SkIsrRetVar irqreturn_t
185#define SkIsrRetNone IRQ_NONE
186#define SkIsrRetHandled IRQ_HANDLED
187
188
189/*******************************************************************************
190 *
191 * Local Function Prototypes
192 *
193 ******************************************************************************/
194
195static void FreeResources(struct SK_NET_DEVICE *dev);
196static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
197static SK_BOOL BoardAllocMem(SK_AC *pAC);
198static void BoardFreeMem(SK_AC *pAC);
199static void BoardInitMem(SK_AC *pAC);
200static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
201static SkIsrRetVar SkGeIsr(int irq, void *dev_id);
202static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id);
203static int SkGeOpen(struct SK_NET_DEVICE *dev);
204static int SkGeClose(struct SK_NET_DEVICE *dev);
205static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
206static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
207static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);
208static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
209static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
210static void GetConfiguration(SK_AC*);
211static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
212static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
213static void FillRxRing(SK_AC*, RX_PORT*);
214static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
215static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
216static void ClearAndStartRx(SK_AC*, int);
217static void ClearTxIrq(SK_AC*, int, int);
218static void ClearRxRing(SK_AC*, RX_PORT*);
219static void ClearTxRing(SK_AC*, TX_PORT*);
220static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
221static void PortReInitBmu(SK_AC*, int);
222static int SkGeIocMib(DEV_NET*, unsigned int, int);
223static int SkGeInitPCI(SK_AC *pAC);
224static void StartDrvCleanupTimer(SK_AC *pAC);
225static void StopDrvCleanupTimer(SK_AC *pAC);
226static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
227
228#ifdef SK_DIAG_SUPPORT
229static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName);
230static int SkDrvInitAdapter(SK_AC *pAC, int devNbr);
231static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
232#endif
233
234/*******************************************************************************
235 *
236 * Extern Function Prototypes
237 *
238 ******************************************************************************/
239extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
240extern void SkDimDisplayModerationSettings(SK_AC *pAC);
241extern void SkDimStartModerationTimer(SK_AC *pAC);
242extern void SkDimModerate(SK_AC *pAC);
243extern void SkGeBlinkTimer(unsigned long data);
244
245#ifdef DEBUG
246static void DumpMsg(struct sk_buff*, char*);
247static void DumpData(char*, int);
248static void DumpLong(char*, int);
249#endif
250
251/* global variables *********************************************************/
252static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
253extern const struct ethtool_ops SkGeEthtoolOps;
254
255/* local variables **********************************************************/
256static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
257static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
258
259/*****************************************************************************
260 *
261 * SkPciWriteCfgDWord - write a 32 bit value to pci config space
262 *
263 * Description:
264 * This routine writes a 32 bit value to the pci configuration
265 * space.
266 *
267 * Returns:
268 * 0 - indicate everything worked ok.
269 * != 0 - error indication
270 */
271static inline int SkPciWriteCfgDWord(
272SK_AC *pAC, /* Adapter Control structure pointer */
273int PciAddr, /* PCI register address */
274SK_U32 Val) /* pointer to store the read value */
275{
276 pci_write_config_dword(pAC->PciDev, PciAddr, Val);
277 return(0);
278} /* SkPciWriteCfgDWord */
279
280/*****************************************************************************
281 *
282 * SkGeInitPCI - Init the PCI resources
283 *
284 * Description:
285 * This function initialize the PCI resources and IO
286 *
287 * Returns:
288 * 0 - indicate everything worked ok.
289 * != 0 - error indication
290 */
291static __devinit int SkGeInitPCI(SK_AC *pAC)
292{
293 struct SK_NET_DEVICE *dev = pAC->dev[0];
294 struct pci_dev *pdev = pAC->PciDev;
295 int retval;
296
297 dev->mem_start = pci_resource_start (pdev, 0);
298 pci_set_master(pdev);
299
300 retval = pci_request_regions(pdev, "sk98lin");
301 if (retval)
302 goto out;
303
304#ifdef SK_BIG_ENDIAN
305 /*
306 * On big endian machines, we use the adapter's aibility of
307 * reading the descriptors as big endian.
308 */
309 {
310 SK_U32 our2;
311 SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
312 our2 |= PCI_REV_DESC;
313 SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
314 }
315#endif
316
317 /*
318 * Remap the regs into kernel space.
319 */
320 pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
321 if (!pAC->IoBase) {
322 retval = -EIO;
323 goto out_release;
324 }
325
326 return 0;
327
328 out_release:
329 pci_release_regions(pdev);
330 out:
331 return retval;
332}
333
334
335/*****************************************************************************
336 *
337 * FreeResources - release resources allocated for adapter
338 *
339 * Description:
340 * This function releases the IRQ, unmaps the IO and
341 * frees the desriptor ring.
342 *
343 * Returns: N/A
344 *
345 */
346static void FreeResources(struct SK_NET_DEVICE *dev)
347{
348SK_U32 AllocFlag;
349DEV_NET *pNet;
350SK_AC *pAC;
351
352 pNet = netdev_priv(dev);
353 pAC = pNet->pAC;
354 AllocFlag = pAC->AllocFlag;
355 if (pAC->PciDev) {
356 pci_release_regions(pAC->PciDev);
357 }
358 if (AllocFlag & SK_ALLOC_IRQ) {
359 free_irq(dev->irq, dev);
360 }
361 if (pAC->IoBase) {
362 iounmap(pAC->IoBase);
363 }
364 if (pAC->pDescrMem) {
365 BoardFreeMem(pAC);
366 }
367
368} /* FreeResources */
369
370MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
371MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
372MODULE_LICENSE("GPL");
373
374#ifdef LINK_SPEED_A
375static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
376#else
377static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
378#endif
379
380#ifdef LINK_SPEED_B
381static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;
382#else
383static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
384#endif
385
386#ifdef AUTO_NEG_A
387static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
388#else
389static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
390#endif
391
392#ifdef DUP_CAP_A
393static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
394#else
395static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
396#endif
397
398#ifdef FLOW_CTRL_A
399static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
400#else
401static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
402#endif
403
404#ifdef ROLE_A
405static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
406#else
407static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
408#endif
409
410#ifdef AUTO_NEG_B
411static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
412#else
413static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
414#endif
415
416#ifdef DUP_CAP_B
417static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
418#else
419static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
420#endif
421
422#ifdef FLOW_CTRL_B
423static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
424#else
425static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
426#endif
427
428#ifdef ROLE_B
429static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
430#else
431static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
432#endif
433
434#ifdef CON_TYPE
435static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;
436#else
437static char *ConType[SK_MAX_CARD_PARAM] = {"", };
438#endif
439
440#ifdef PREF_PORT
441static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
442#else
443static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
444#endif
445
446#ifdef RLMT_MODE
447static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
448#else
449static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
450#endif
451
452static int IntsPerSec[SK_MAX_CARD_PARAM];
453static char *Moderation[SK_MAX_CARD_PARAM];
454static char *ModerationMask[SK_MAX_CARD_PARAM];
455static char *AutoSizing[SK_MAX_CARD_PARAM];
456static char *Stats[SK_MAX_CARD_PARAM];
457
458module_param_array(Speed_A, charp, NULL, 0);
459module_param_array(Speed_B, charp, NULL, 0);
460module_param_array(AutoNeg_A, charp, NULL, 0);
461module_param_array(AutoNeg_B, charp, NULL, 0);
462module_param_array(DupCap_A, charp, NULL, 0);
463module_param_array(DupCap_B, charp, NULL, 0);
464module_param_array(FlowCtrl_A, charp, NULL, 0);
465module_param_array(FlowCtrl_B, charp, NULL, 0);
466module_param_array(Role_A, charp, NULL, 0);
467module_param_array(Role_B, charp, NULL, 0);
468module_param_array(ConType, charp, NULL, 0);
469module_param_array(PrefPort, charp, NULL, 0);
470module_param_array(RlmtMode, charp, NULL, 0);
471/* used for interrupt moderation */
472module_param_array(IntsPerSec, int, NULL, 0);
473module_param_array(Moderation, charp, NULL, 0);
474module_param_array(Stats, charp, NULL, 0);
475module_param_array(ModerationMask, charp, NULL, 0);
476module_param_array(AutoSizing, charp, NULL, 0);
477
478/*****************************************************************************
479 *
480 * SkGeBoardInit - do level 0 and 1 initialization
481 *
482 * Description:
483 * This function prepares the board hardware for running. The desriptor
484 * ring is set up, the IRQ is allocated and the configuration settings
485 * are examined.
486 *
487 * Returns:
488 * 0, if everything is ok
489 * !=0, on error
490 */
491static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
492{
493short i;
494unsigned long Flags;
495char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
496char *VerStr = VER_STRING;
497int Ret; /* return code of request_irq */
498SK_BOOL DualNet;
499
500 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
501 ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
502 for (i=0; i<SK_MAX_MACS; i++) {
503 pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
504 pAC->TxPort[i][0].PortIndex = i;
505 pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
506 pAC->RxPort[i].PortIndex = i;
507 }
508
509 /* Initialize the mutexes */
510 for (i=0; i<SK_MAX_MACS; i++) {
511 spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
512 spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
513 }
514 spin_lock_init(&pAC->SlowPathLock);
515
516 /* setup phy_id blink timer */
517 pAC->BlinkTimer.function = SkGeBlinkTimer;
518 pAC->BlinkTimer.data = (unsigned long) dev;
519 init_timer(&pAC->BlinkTimer);
520
521 /* level 0 init common modules here */
522
523 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
524 /* Does a RESET on board ...*/
525 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
526 printk("HWInit (0) failed.\n");
527 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
528 return -EIO;
529 }
530 SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
531 SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
532 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA);
533 SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
534 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
535 SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
536
537 pAC->BoardLevel = SK_INIT_DATA;
538 pAC->RxBufSize = ETH_BUF_SIZE;
539
540 SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
541 SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
542
543 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
544
545 /* level 1 init common modules here (HW init) */
546 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
547 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
548 printk("sk98lin: HWInit (1) failed.\n");
549 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
550 return -EIO;
551 }
552 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
553 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
554 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
555 SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
556 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
557 SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
558
559 /* Set chipset type support */
560 pAC->ChipsetType = 0;
561 if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
562 (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
563 pAC->ChipsetType = 1;
564 }
565
566 GetConfiguration(pAC);
567 if (pAC->RlmtNets == 2) {
568 pAC->GIni.GIPortUsage = SK_MUL_LINK;
569 }
570
571 pAC->BoardLevel = SK_INIT_IO;
572 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
573
574 if (pAC->GIni.GIMacsFound == 2) {
575 Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
576 } else if (pAC->GIni.GIMacsFound == 1) {
577 Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED,
578 "sk98lin", dev);
579 } else {
580 printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
581 pAC->GIni.GIMacsFound);
582 return -EIO;
583 }
584
585 if (Ret) {
586 printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
587 dev->irq);
588 return Ret;
589 }
590 pAC->AllocFlag |= SK_ALLOC_IRQ;
591
592 /* Alloc memory for this board (Mem for RxD/TxD) : */
593 if(!BoardAllocMem(pAC)) {
594 printk("No memory for descriptor rings.\n");
595 return -ENOMEM;
596 }
597
598 BoardInitMem(pAC);
599 /* tschilling: New common function with minimum size check. */
600 DualNet = SK_FALSE;
601 if (pAC->RlmtNets == 2) {
602 DualNet = SK_TRUE;
603 }
604
605 if (SkGeInitAssignRamToQueues(
606 pAC,
607 pAC->ActivePort,
608 DualNet)) {
609 BoardFreeMem(pAC);
610 printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
611 return -EIO;
612 }
613
614 return (0);
615} /* SkGeBoardInit */
616
617
618/*****************************************************************************
619 *
620 * BoardAllocMem - allocate the memory for the descriptor rings
621 *
622 * Description:
623 * This function allocates the memory for all descriptor rings.
624 * Each ring is aligned for the desriptor alignment and no ring
625 * has a 4 GByte boundary in it (because the upper 32 bit must
626 * be constant for all descriptiors in one rings).
627 *
628 * Returns:
629 * SK_TRUE, if all memory could be allocated
630 * SK_FALSE, if not
631 */
632static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC)
633{
634caddr_t pDescrMem; /* pointer to descriptor memory area */
635size_t AllocLength; /* length of complete descriptor area */
636int i; /* loop counter */
637unsigned long BusAddr;
638
639
640 /* rings plus one for alignment (do not cross 4 GB boundary) */
641 /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
642#if (BITS_PER_LONG == 32)
643 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
644#else
645 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
646 + RX_RING_SIZE + 8;
647#endif
648
649 pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
650 &pAC->pDescrMemDMA);
651
652 if (pDescrMem == NULL) {
653 return (SK_FALSE);
654 }
655 pAC->pDescrMem = pDescrMem;
656 BusAddr = (unsigned long) pAC->pDescrMemDMA;
657
658 /* Descriptors need 8 byte alignment, and this is ensured
659 * by pci_alloc_consistent.
660 */
661 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
662 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
663 ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n",
664 i, (unsigned long) pDescrMem,
665 BusAddr));
666 pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
667 pAC->TxPort[i][0].VTxDescrRing = BusAddr;
668 pDescrMem += TX_RING_SIZE;
669 BusAddr += TX_RING_SIZE;
670
671 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
672 ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n",
673 i, (unsigned long) pDescrMem,
674 (unsigned long)BusAddr));
675 pAC->RxPort[i].pRxDescrRing = pDescrMem;
676 pAC->RxPort[i].VRxDescrRing = BusAddr;
677 pDescrMem += RX_RING_SIZE;
678 BusAddr += RX_RING_SIZE;
679 } /* for */
680
681 return (SK_TRUE);
682} /* BoardAllocMem */
683
684
685/****************************************************************************
686 *
687 * BoardFreeMem - reverse of BoardAllocMem
688 *
689 * Description:
690 * Free all memory allocated in BoardAllocMem: adapter context,
691 * descriptor rings, locks.
692 *
693 * Returns: N/A
694 */
695static void BoardFreeMem(
696SK_AC *pAC)
697{
698size_t AllocLength; /* length of complete descriptor area */
699
700 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
701 ("BoardFreeMem\n"));
702#if (BITS_PER_LONG == 32)
703 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
704#else
705 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
706 + RX_RING_SIZE + 8;
707#endif
708
709 pci_free_consistent(pAC->PciDev, AllocLength,
710 pAC->pDescrMem, pAC->pDescrMemDMA);
711 pAC->pDescrMem = NULL;
712} /* BoardFreeMem */
713
714
715/*****************************************************************************
716 *
717 * BoardInitMem - initiate the descriptor rings
718 *
719 * Description:
720 * This function sets the descriptor rings up in memory.
721 * The adapter is initialized with the descriptor start addresses.
722 *
723 * Returns: N/A
724 */
725static __devinit void BoardInitMem(SK_AC *pAC)
726{
727int i; /* loop counter */
728int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
729int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/
730
731 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
732 ("BoardInitMem\n"));
733
734 RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
735 pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
736 TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
737 pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
738
739 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
740 SetupRing(
741 pAC,
742 pAC->TxPort[i][0].pTxDescrRing,
743 pAC->TxPort[i][0].VTxDescrRing,
744 (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
745 (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
746 (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
747 &pAC->TxPort[i][0].TxdRingFree,
748 SK_TRUE);
749 SetupRing(
750 pAC,
751 pAC->RxPort[i].pRxDescrRing,
752 pAC->RxPort[i].VRxDescrRing,
753 &pAC->RxPort[i].pRxdRingHead,
754 &pAC->RxPort[i].pRxdRingTail,
755 &pAC->RxPort[i].pRxdRingPrev,
756 &pAC->RxPort[i].RxdRingFree,
757 SK_FALSE);
758 }
759} /* BoardInitMem */
760
761
762/*****************************************************************************
763 *
764 * SetupRing - create one descriptor ring
765 *
766 * Description:
767 * This function creates one descriptor ring in the given memory area.
768 * The head, tail and number of free descriptors in the ring are set.
769 *
770 * Returns:
771 * none
772 */
773static void SetupRing(
774SK_AC *pAC,
775void *pMemArea, /* a pointer to the memory area for the ring */
776uintptr_t VMemArea, /* the virtual bus address of the memory area */
777RXD **ppRingHead, /* address where the head should be written */
778RXD **ppRingTail, /* address where the tail should be written */
779RXD **ppRingPrev, /* address where the tail should be written */
780int *pRingFree, /* address where the # of free descr. goes */
781SK_BOOL IsTx) /* flag: is this a tx ring */
782{
783int i; /* loop counter */
784int DescrSize; /* the size of a descriptor rounded up to alignment*/
785int DescrNum; /* number of descriptors per ring */
786RXD *pDescr; /* pointer to a descriptor (receive or transmit) */
787RXD *pNextDescr; /* pointer to the next descriptor */
788RXD *pPrevDescr; /* pointer to the previous descriptor */
789uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */
790
791 if (IsTx == SK_TRUE) {
792 DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
793 DESCR_ALIGN;
794 DescrNum = TX_RING_SIZE / DescrSize;
795 } else {
796 DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
797 DESCR_ALIGN;
798 DescrNum = RX_RING_SIZE / DescrSize;
799 }
800
801 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
802 ("Descriptor size: %d Descriptor Number: %d\n",
803 DescrSize,DescrNum));
804
805 pDescr = (RXD*) pMemArea;
806 pPrevDescr = NULL;
807 pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
808 VNextDescr = VMemArea + DescrSize;
809 for(i=0; i<DescrNum; i++) {
810 /* set the pointers right */
811 pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
812 pDescr->pNextRxd = pNextDescr;
813 if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN;
814
815 /* advance one step */
816 pPrevDescr = pDescr;
817 pDescr = pNextDescr;
818 pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
819 VNextDescr += DescrSize;
820 }
821 pPrevDescr->pNextRxd = (RXD*) pMemArea;
822 pPrevDescr->VNextRxd = VMemArea;
823 pDescr = (RXD*) pMemArea;
824 *ppRingHead = (RXD*) pMemArea;
825 *ppRingTail = *ppRingHead;
826 *ppRingPrev = pPrevDescr;
827 *pRingFree = DescrNum;
828} /* SetupRing */
829
830
831/*****************************************************************************
832 *
833 * PortReInitBmu - re-initiate the descriptor rings for one port
834 *
835 * Description:
836 * This function reinitializes the descriptor rings of one port
837 * in memory. The port must be stopped before.
838 * The HW is initialized with the descriptor start addresses.
839 *
840 * Returns:
841 * none
842 */
843static void PortReInitBmu(
844SK_AC *pAC, /* pointer to adapter context */
845int PortIndex) /* index of the port for which to re-init */
846{
847 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
848 ("PortReInitBmu "));
849
850 /* set address of first descriptor of ring in BMU */
851 SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L,
852 (uint32_t)(((caddr_t)
853 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
854 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
855 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
856 0xFFFFFFFF));
857 SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H,
858 (uint32_t)(((caddr_t)
859 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
860 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
861 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
862 SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L,
863 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
864 pAC->RxPort[PortIndex].pRxDescrRing +
865 pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
866 SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H,
867 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
868 pAC->RxPort[PortIndex].pRxDescrRing +
869 pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
870} /* PortReInitBmu */
871
872
873/****************************************************************************
874 *
875 * SkGeIsr - handle adapter interrupts
876 *
877 * Description:
878 * The interrupt routine is called when the network adapter
879 * generates an interrupt. It may also be called if another device
880 * shares this interrupt vector with the driver.
881 *
882 * Returns: N/A
883 *
884 */
885static SkIsrRetVar SkGeIsr(int irq, void *dev_id)
886{
887struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
888DEV_NET *pNet;
889SK_AC *pAC;
890SK_U32 IntSrc; /* interrupts source register contents */
891
892 pNet = netdev_priv(dev);
893 pAC = pNet->pAC;
894
895 /*
896 * Check and process if its our interrupt
897 */
898 SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
899 if (IntSrc == 0) {
900 return SkIsrRetNone;
901 }
902
903 while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
904#if 0 /* software irq currently not used */
905 if (IntSrc & IS_IRQ_SW) {
906 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
907 SK_DBGCAT_DRV_INT_SRC,
908 ("Software IRQ\n"));
909 }
910#endif
911 if (IntSrc & IS_R1_F) {
912 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
913 SK_DBGCAT_DRV_INT_SRC,
914 ("EOF RX1 IRQ\n"));
915 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
916 SK_PNMI_CNT_RX_INTR(pAC, 0);
917 }
918 if (IntSrc & IS_R2_F) {
919 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
920 SK_DBGCAT_DRV_INT_SRC,
921 ("EOF RX2 IRQ\n"));
922 ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
923 SK_PNMI_CNT_RX_INTR(pAC, 1);
924 }
925#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
926 if (IntSrc & IS_XA1_F) {
927 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
928 SK_DBGCAT_DRV_INT_SRC,
929 ("EOF AS TX1 IRQ\n"));
930 SK_PNMI_CNT_TX_INTR(pAC, 0);
931 spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
932 FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
933 spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
934 }
935 if (IntSrc & IS_XA2_F) {
936 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
937 SK_DBGCAT_DRV_INT_SRC,
938 ("EOF AS TX2 IRQ\n"));
939 SK_PNMI_CNT_TX_INTR(pAC, 1);
940 spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
941 FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
942 spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
943 }
944#if 0 /* only if sync. queues used */
945 if (IntSrc & IS_XS1_F) {
946 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
947 SK_DBGCAT_DRV_INT_SRC,
948 ("EOF SY TX1 IRQ\n"));
949 SK_PNMI_CNT_TX_INTR(pAC, 1);
950 spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
951 FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
952 spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
953 ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
954 }
955 if (IntSrc & IS_XS2_F) {
956 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
957 SK_DBGCAT_DRV_INT_SRC,
958 ("EOF SY TX2 IRQ\n"));
959 SK_PNMI_CNT_TX_INTR(pAC, 1);
960 spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
961 FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
962 spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
963 ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
964 }
965#endif
966#endif
967
968 /* do all IO at once */
969 if (IntSrc & IS_R1_F)
970 ClearAndStartRx(pAC, 0);
971 if (IntSrc & IS_R2_F)
972 ClearAndStartRx(pAC, 1);
973#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
974 if (IntSrc & IS_XA1_F)
975 ClearTxIrq(pAC, 0, TX_PRIO_LOW);
976 if (IntSrc & IS_XA2_F)
977 ClearTxIrq(pAC, 1, TX_PRIO_LOW);
978#endif
979 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
980 } /* while (IntSrc & IRQ_MASK != 0) */
981
982 IntSrc &= pAC->GIni.GIValIrqMask;
983 if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
984 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
985 ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
986 pAC->CheckQueue = SK_FALSE;
987 spin_lock(&pAC->SlowPathLock);
988 if (IntSrc & SPECIAL_IRQS)
989 SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
990
991 SkEventDispatcher(pAC, pAC->IoBase);
992 spin_unlock(&pAC->SlowPathLock);
993 }
994 /*
995 * do it all again is case we cleared an interrupt that
996 * came in after handling the ring (OUTs may be delayed
997 * in hardware buffers, but are through after IN)
998 *
999 * rroesler: has been commented out and shifted to
1000 * SkGeDrvEvent(), because it is timer
1001 * guarded now
1002 *
1003 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1004 ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
1005 */
1006
1007 if (pAC->CheckQueue) {
1008 pAC->CheckQueue = SK_FALSE;
1009 spin_lock(&pAC->SlowPathLock);
1010 SkEventDispatcher(pAC, pAC->IoBase);
1011 spin_unlock(&pAC->SlowPathLock);
1012 }
1013
1014 /* IRQ is processed - Enable IRQs again*/
1015 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1016
1017 return SkIsrRetHandled;
1018} /* SkGeIsr */
1019
1020
1021/****************************************************************************
1022 *
1023 * SkGeIsrOnePort - handle adapter interrupts for single port adapter
1024 *
1025 * Description:
1026 * The interrupt routine is called when the network adapter
1027 * generates an interrupt. It may also be called if another device
1028 * shares this interrupt vector with the driver.
1029 * This is the same as above, but handles only one port.
1030 *
1031 * Returns: N/A
1032 *
1033 */
1034static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id)
1035{
1036struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
1037DEV_NET *pNet;
1038SK_AC *pAC;
1039SK_U32 IntSrc; /* interrupts source register contents */
1040
1041 pNet = netdev_priv(dev);
1042 pAC = pNet->pAC;
1043
1044 /*
1045 * Check and process if its our interrupt
1046 */
1047 SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
1048 if (IntSrc == 0) {
1049 return SkIsrRetNone;
1050 }
1051
1052 while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
1053#if 0 /* software irq currently not used */
1054 if (IntSrc & IS_IRQ_SW) {
1055 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1056 SK_DBGCAT_DRV_INT_SRC,
1057 ("Software IRQ\n"));
1058 }
1059#endif
1060 if (IntSrc & IS_R1_F) {
1061 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1062 SK_DBGCAT_DRV_INT_SRC,
1063 ("EOF RX1 IRQ\n"));
1064 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1065 SK_PNMI_CNT_RX_INTR(pAC, 0);
1066 }
1067#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1068 if (IntSrc & IS_XA1_F) {
1069 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1070 SK_DBGCAT_DRV_INT_SRC,
1071 ("EOF AS TX1 IRQ\n"));
1072 SK_PNMI_CNT_TX_INTR(pAC, 0);
1073 spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1074 FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
1075 spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1076 }
1077#if 0 /* only if sync. queues used */
1078 if (IntSrc & IS_XS1_F) {
1079 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1080 SK_DBGCAT_DRV_INT_SRC,
1081 ("EOF SY TX1 IRQ\n"));
1082 SK_PNMI_CNT_TX_INTR(pAC, 0);
1083 spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1084 FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
1085 spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1086 ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
1087 }
1088#endif
1089#endif
1090
1091 /* do all IO at once */
1092 if (IntSrc & IS_R1_F)
1093 ClearAndStartRx(pAC, 0);
1094#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1095 if (IntSrc & IS_XA1_F)
1096 ClearTxIrq(pAC, 0, TX_PRIO_LOW);
1097#endif
1098 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
1099 } /* while (IntSrc & IRQ_MASK != 0) */
1100
1101 IntSrc &= pAC->GIni.GIValIrqMask;
1102 if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
1103 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
1104 ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
1105 pAC->CheckQueue = SK_FALSE;
1106 spin_lock(&pAC->SlowPathLock);
1107 if (IntSrc & SPECIAL_IRQS)
1108 SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1109
1110 SkEventDispatcher(pAC, pAC->IoBase);
1111 spin_unlock(&pAC->SlowPathLock);
1112 }
1113 /*
1114 * do it all again is case we cleared an interrupt that
1115 * came in after handling the ring (OUTs may be delayed
1116 * in hardware buffers, but are through after IN)
1117 *
1118 * rroesler: has been commented out and shifted to
1119 * SkGeDrvEvent(), because it is timer
1120 * guarded now
1121 *
1122 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1123 */
1124
1125 /* IRQ is processed - Enable IRQs again*/
1126 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1127
1128 return SkIsrRetHandled;
1129} /* SkGeIsrOnePort */
1130
1131#ifdef CONFIG_NET_POLL_CONTROLLER
1132/****************************************************************************
1133 *
1134 * SkGePollController - polling receive, for netconsole
1135 *
1136 * Description:
1137 * Polling receive - used by netconsole and other diagnostic tools
1138 * to allow network i/o with interrupts disabled.
1139 *
1140 * Returns: N/A
1141 */
1142static void SkGePollController(struct net_device *dev)
1143{
1144 disable_irq(dev->irq);
1145 SkGeIsr(dev->irq, dev);
1146 enable_irq(dev->irq);
1147}
1148#endif
1149
1150/****************************************************************************
1151 *
1152 * SkGeOpen - handle start of initialized adapter
1153 *
1154 * Description:
1155 * This function starts the initialized adapter.
1156 * The board level variable is set and the adapter is
1157 * brought to full functionality.
1158 * The device flags are set for operation.
1159 * Do all necessary level 2 initialization, enable interrupts and
1160 * give start command to RLMT.
1161 *
1162 * Returns:
1163 * 0 on success
1164 * != 0 on error
1165 */
1166static int SkGeOpen(
1167struct SK_NET_DEVICE *dev)
1168{
1169 DEV_NET *pNet;
1170 SK_AC *pAC;
1171 unsigned long Flags; /* for spin lock */
1172 int i;
1173 SK_EVPARA EvPara; /* an event parameter union */
1174
1175 pNet = netdev_priv(dev);
1176 pAC = pNet->pAC;
1177
1178 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1179 ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
1180
1181#ifdef SK_DIAG_SUPPORT
1182 if (pAC->DiagModeActive == DIAG_ACTIVE) {
1183 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
1184 return (-1); /* still in use by diag; deny actions */
1185 }
1186 }
1187#endif
1188
1189 /* Set blink mode */
1190 if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
1191 pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
1192
1193 if (pAC->BoardLevel == SK_INIT_DATA) {
1194 /* level 1 init common modules here */
1195 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
1196 printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
1197 return (-1);
1198 }
1199 SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO);
1200 SkEventInit (pAC, pAC->IoBase, SK_INIT_IO);
1201 SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO);
1202 SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO);
1203 SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO);
1204 SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO);
1205 pAC->BoardLevel = SK_INIT_IO;
1206 }
1207
1208 if (pAC->BoardLevel != SK_INIT_RUN) {
1209 /* tschilling: Level 2 init modules here, check return value. */
1210 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
1211 printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
1212 return (-1);
1213 }
1214 SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN);
1215 SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN);
1216 SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN);
1217 SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN);
1218 SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN);
1219 SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN);
1220 pAC->BoardLevel = SK_INIT_RUN;
1221 }
1222
1223 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1224 /* Enable transmit descriptor polling. */
1225 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
1226 FillRxRing(pAC, &pAC->RxPort[i]);
1227 }
1228 SkGeYellowLED(pAC, pAC->IoBase, 1);
1229
1230 StartDrvCleanupTimer(pAC);
1231 SkDimEnableModerationIfNeeded(pAC);
1232 SkDimDisplayModerationSettings(pAC);
1233
1234 pAC->GIni.GIValIrqMask &= IRQ_MASK;
1235
1236 /* enable Interrupts */
1237 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1238 SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
1239
1240 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1241
1242 if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
1243 EvPara.Para32[0] = pAC->RlmtNets;
1244 EvPara.Para32[1] = -1;
1245 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
1246 EvPara);
1247 EvPara.Para32[0] = pAC->RlmtMode;
1248 EvPara.Para32[1] = 0;
1249 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
1250 EvPara);
1251 }
1252
1253 EvPara.Para32[0] = pNet->NetNr;
1254 EvPara.Para32[1] = -1;
1255 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
1256 SkEventDispatcher(pAC, pAC->IoBase);
1257 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1258
1259 pAC->MaxPorts++;
1260
1261
1262 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1263 ("SkGeOpen suceeded\n"));
1264
1265 return (0);
1266} /* SkGeOpen */
1267
1268
1269/****************************************************************************
1270 *
1271 * SkGeClose - Stop initialized adapter
1272 *
1273 * Description:
1274 * Close initialized adapter.
1275 *
1276 * Returns:
1277 * 0 - on success
1278 * error code - on error
1279 */
1280static int SkGeClose(
1281struct SK_NET_DEVICE *dev)
1282{
1283 DEV_NET *pNet;
1284 DEV_NET *newPtrNet;
1285 SK_AC *pAC;
1286
1287 unsigned long Flags; /* for spin lock */
1288 int i;
1289 int PortIdx;
1290 SK_EVPARA EvPara;
1291
1292 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1293 ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
1294
1295 pNet = netdev_priv(dev);
1296 pAC = pNet->pAC;
1297
1298#ifdef SK_DIAG_SUPPORT
1299 if (pAC->DiagModeActive == DIAG_ACTIVE) {
1300 if (pAC->DiagFlowCtrl == SK_FALSE) {
1301 /*
1302 ** notify that the interface which has been closed
1303 ** by operator interaction must not be started up
1304 ** again when the DIAG has finished.
1305 */
1306 newPtrNet = netdev_priv(pAC->dev[0]);
1307 if (newPtrNet == pNet) {
1308 pAC->WasIfUp[0] = SK_FALSE;
1309 } else {
1310 pAC->WasIfUp[1] = SK_FALSE;
1311 }
1312 return 0; /* return to system everything is fine... */
1313 } else {
1314 pAC->DiagFlowCtrl = SK_FALSE;
1315 }
1316 }
1317#endif
1318
1319 netif_stop_queue(dev);
1320
1321 if (pAC->RlmtNets == 1)
1322 PortIdx = pAC->ActivePort;
1323 else
1324 PortIdx = pNet->NetNr;
1325
1326 StopDrvCleanupTimer(pAC);
1327
1328 /*
1329 * Clear multicast table, promiscuous mode ....
1330 */
1331 SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
1332 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
1333 SK_PROM_MODE_NONE);
1334
1335 if (pAC->MaxPorts == 1) {
1336 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1337 /* disable interrupts */
1338 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1339 EvPara.Para32[0] = pNet->NetNr;
1340 EvPara.Para32[1] = -1;
1341 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1342 SkEventDispatcher(pAC, pAC->IoBase);
1343 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1344 /* stop the hardware */
1345 SkGeDeInit(pAC, pAC->IoBase);
1346 pAC->BoardLevel = SK_INIT_DATA;
1347 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1348 } else {
1349
1350 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1351 EvPara.Para32[0] = pNet->NetNr;
1352 EvPara.Para32[1] = -1;
1353 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1354 SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
1355 SkEventDispatcher(pAC, pAC->IoBase);
1356 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1357
1358 /* Stop port */
1359 spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
1360 [TX_PRIO_LOW].TxDesRingLock, Flags);
1361 SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
1362 SK_STOP_ALL, SK_HARD_RST);
1363 spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
1364 [TX_PRIO_LOW].TxDesRingLock, Flags);
1365 }
1366
1367 if (pAC->RlmtNets == 1) {
1368 /* clear all descriptor rings */
1369 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1370 ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
1371 ClearRxRing(pAC, &pAC->RxPort[i]);
1372 ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
1373 }
1374 } else {
1375 /* clear port descriptor rings */
1376 ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
1377 ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
1378 ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
1379 }
1380
1381 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1382 ("SkGeClose: done "));
1383
1384 SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
1385 SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct),
1386 sizeof(SK_PNMI_STRUCT_DATA));
1387
1388 pAC->MaxPorts--;
1389
1390 return (0);
1391} /* SkGeClose */
1392
1393
1394/*****************************************************************************
1395 *
1396 * SkGeXmit - Linux frame transmit function
1397 *
1398 * Description:
1399 * The system calls this function to send frames onto the wire.
1400 * It puts the frame in the tx descriptor ring. If the ring is
1401 * full then, the 'tbusy' flag is set.
1402 *
1403 * Returns:
1404 * 0, if everything is ok
1405 * !=0, on error
1406 * WARNING: returning 1 in 'tbusy' case caused system crashes (double
1407 * allocated skb's) !!!
1408 */
1409static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
1410{
1411DEV_NET *pNet;
1412SK_AC *pAC;
1413int Rc; /* return code of XmitFrame */
1414
1415 pNet = netdev_priv(dev);
1416 pAC = pNet->pAC;
1417
1418 if ((!skb_shinfo(skb)->nr_frags) ||
1419 (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
1420 /* Don't activate scatter-gather and hardware checksum */
1421
1422 if (pAC->RlmtNets == 2)
1423 Rc = XmitFrame(
1424 pAC,
1425 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1426 skb);
1427 else
1428 Rc = XmitFrame(
1429 pAC,
1430 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1431 skb);
1432 } else {
1433 /* scatter-gather and hardware TCP checksumming anabled*/
1434 if (pAC->RlmtNets == 2)
1435 Rc = XmitFrameSG(
1436 pAC,
1437 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1438 skb);
1439 else
1440 Rc = XmitFrameSG(
1441 pAC,
1442 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1443 skb);
1444 }
1445
1446 /* Transmitter out of resources? */
1447 if (Rc <= 0) {
1448 netif_stop_queue(dev);
1449 }
1450
1451 /* If not taken, give buffer ownership back to the
1452 * queueing layer.
1453 */
1454 if (Rc < 0)
1455 return (1);
1456
1457 dev->trans_start = jiffies;
1458 return (0);
1459} /* SkGeXmit */
1460
1461
1462/*****************************************************************************
1463 *
1464 * XmitFrame - fill one socket buffer into the transmit ring
1465 *
1466 * Description:
1467 * This function puts a message into the transmit descriptor ring
1468 * if there is a descriptors left.
1469 * Linux skb's consist of only one continuous buffer.
1470 * The first step locks the ring. It is held locked
1471 * all time to avoid problems with SWITCH_../PORT_RESET.
1472 * Then the descriptoris allocated.
1473 * The second part is linking the buffer to the descriptor.
1474 * At the very last, the Control field of the descriptor
1475 * is made valid for the BMU and a start TX command is given
1476 * if necessary.
1477 *
1478 * Returns:
1479 * > 0 - on succes: the number of bytes in the message
1480 * = 0 - on resource shortage: this frame sent or dropped, now
1481 * the ring is full ( -> set tbusy)
1482 * < 0 - on failure: other problems ( -> return failure to upper layers)
1483 */
1484static int XmitFrame(
1485SK_AC *pAC, /* pointer to adapter context */
1486TX_PORT *pTxPort, /* pointer to struct of port to send to */
1487struct sk_buff *pMessage) /* pointer to send-message */
1488{
1489 TXD *pTxd; /* the rxd to fill */
1490 TXD *pOldTxd;
1491 unsigned long Flags;
1492 SK_U64 PhysAddr;
1493 int BytesSend = pMessage->len;
1494
1495 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
1496
1497 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1498#ifndef USE_TX_COMPLETE
1499 FreeTxDescriptors(pAC, pTxPort);
1500#endif
1501 if (pTxPort->TxdRingFree == 0) {
1502 /*
1503 ** no enough free descriptors in ring at the moment.
1504 ** Maybe free'ing some old one help?
1505 */
1506 FreeTxDescriptors(pAC, pTxPort);
1507 if (pTxPort->TxdRingFree == 0) {
1508 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1509 SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1510 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1511 SK_DBGCAT_DRV_TX_PROGRESS,
1512 ("XmitFrame failed\n"));
1513 /*
1514 ** the desired message can not be sent
1515 ** Because tbusy seems to be set, the message
1516 ** should not be freed here. It will be used
1517 ** by the scheduler of the ethernet handler
1518 */
1519 return (-1);
1520 }
1521 }
1522
1523 /*
1524 ** If the passed socket buffer is of smaller MTU-size than 60,
1525 ** copy everything into new buffer and fill all bytes between
1526 ** the original packet end and the new packet end of 60 with 0x00.
1527 ** This is to resolve faulty padding by the HW with 0xaa bytes.
1528 */
1529 if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
1530 if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) {
1531 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1532 return 0;
1533 }
1534 pMessage->len = C_LEN_ETHERNET_MINSIZE;
1535 }
1536
1537 /*
1538 ** advance head counter behind descriptor needed for this frame,
1539 ** so that needed descriptor is reserved from that on. The next
1540 ** action will be to add the passed buffer to the TX-descriptor
1541 */
1542 pTxd = pTxPort->pTxdRingHead;
1543 pTxPort->pTxdRingHead = pTxd->pNextTxd;
1544 pTxPort->TxdRingFree--;
1545
1546#ifdef SK_DUMP_TX
1547 DumpMsg(pMessage, "XmitFrame");
1548#endif
1549
1550 /*
1551 ** First step is to map the data to be sent via the adapter onto
1552 ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4
1553 ** and 2.6 need to use pci_map_page() for that mapping.
1554 */
1555 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1556 virt_to_page(pMessage->data),
1557 ((unsigned long) pMessage->data & ~PAGE_MASK),
1558 pMessage->len,
1559 PCI_DMA_TODEVICE);
1560 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1561 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1562 pTxd->pMBuf = pMessage;
1563
1564 if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
1565 u16 hdrlen = skb_transport_offset(pMessage);
1566 u16 offset = hdrlen + pMessage->csum_offset;
1567
1568 if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
1569 (pAC->GIni.GIChipRev == 0) &&
1570 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1571 pTxd->TBControl = BMU_TCP_CHECK;
1572 } else {
1573 pTxd->TBControl = BMU_UDP_CHECK;
1574 }
1575
1576 pTxd->TcpSumOfs = 0;
1577 pTxd->TcpSumSt = hdrlen;
1578 pTxd->TcpSumWr = offset;
1579
1580 pTxd->TBControl |= BMU_OWN | BMU_STF |
1581 BMU_SW | BMU_EOF |
1582#ifdef USE_TX_COMPLETE
1583 BMU_IRQ_EOF |
1584#endif
1585 pMessage->len;
1586 } else {
1587 pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK |
1588 BMU_SW | BMU_EOF |
1589#ifdef USE_TX_COMPLETE
1590 BMU_IRQ_EOF |
1591#endif
1592 pMessage->len;
1593 }
1594
1595 /*
1596 ** If previous descriptor already done, give TX start cmd
1597 */
1598 pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd);
1599 if ((pOldTxd->TBControl & BMU_OWN) == 0) {
1600 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1601 }
1602
1603 /*
1604 ** after releasing the lock, the skb may immediately be free'd
1605 */
1606 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1607 if (pTxPort->TxdRingFree != 0) {
1608 return (BytesSend);
1609 } else {
1610 return (0);
1611 }
1612
1613} /* XmitFrame */
1614
1615/*****************************************************************************
1616 *
1617 * XmitFrameSG - fill one socket buffer into the transmit ring
1618 * (use SG and TCP/UDP hardware checksumming)
1619 *
1620 * Description:
1621 * This function puts a message into the transmit descriptor ring
1622 * if there is a descriptors left.
1623 *
1624 * Returns:
1625 * > 0 - on succes: the number of bytes in the message
1626 * = 0 - on resource shortage: this frame sent or dropped, now
1627 * the ring is full ( -> set tbusy)
1628 * < 0 - on failure: other problems ( -> return failure to upper layers)
1629 */
1630static int XmitFrameSG(
1631SK_AC *pAC, /* pointer to adapter context */
1632TX_PORT *pTxPort, /* pointer to struct of port to send to */
1633struct sk_buff *pMessage) /* pointer to send-message */
1634{
1635
1636 TXD *pTxd;
1637 TXD *pTxdFst;
1638 TXD *pTxdLst;
1639 int CurrFrag;
1640 int BytesSend;
1641 skb_frag_t *sk_frag;
1642 SK_U64 PhysAddr;
1643 unsigned long Flags;
1644 SK_U32 Control;
1645
1646 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1647#ifndef USE_TX_COMPLETE
1648 FreeTxDescriptors(pAC, pTxPort);
1649#endif
1650 if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
1651 FreeTxDescriptors(pAC, pTxPort);
1652 if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
1653 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1654 SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1655 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1656 SK_DBGCAT_DRV_TX_PROGRESS,
1657 ("XmitFrameSG failed - Ring full\n"));
1658 /* this message can not be sent now */
1659 return(-1);
1660 }
1661 }
1662
1663 pTxd = pTxPort->pTxdRingHead;
1664 pTxdFst = pTxd;
1665 pTxdLst = pTxd;
1666 BytesSend = 0;
1667
1668 /*
1669 ** Map the first fragment (header) into the DMA-space
1670 */
1671 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1672 virt_to_page(pMessage->data),
1673 ((unsigned long) pMessage->data & ~PAGE_MASK),
1674 skb_headlen(pMessage),
1675 PCI_DMA_TODEVICE);
1676
1677 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1678 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1679
1680 /*
1681 ** Does the HW need to evaluate checksum for TCP or UDP packets?
1682 */
1683 if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
1684 u16 hdrlen = skb_transport_offset(pMessage);
1685 u16 offset = hdrlen + pMessage->csum_offset;
1686
1687 Control = BMU_STFWD;
1688
1689 /*
1690 ** We have to use the opcode for tcp here, because the
1691 ** opcode for udp is not working in the hardware yet
1692 ** (Revision 2.0)
1693 */
1694 if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
1695 (pAC->GIni.GIChipRev == 0) &&
1696 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1697 Control |= BMU_TCP_CHECK;
1698 } else {
1699 Control |= BMU_UDP_CHECK;
1700 }
1701
1702 pTxd->TcpSumOfs = 0;
1703 pTxd->TcpSumSt = hdrlen;
1704 pTxd->TcpSumWr = offset;
1705 } else
1706 Control = BMU_CHECK | BMU_SW;
1707
1708 pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage);
1709
1710 pTxd = pTxd->pNextTxd;
1711 pTxPort->TxdRingFree--;
1712 BytesSend += skb_headlen(pMessage);
1713
1714 /*
1715 ** Browse over all SG fragments and map each of them into the DMA space
1716 */
1717 for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) {
1718 sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag];
1719 /*
1720 ** we already have the proper value in entry
1721 */
1722 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1723 sk_frag->page,
1724 sk_frag->page_offset,
1725 sk_frag->size,
1726 PCI_DMA_TODEVICE);
1727
1728 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1729 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1730 pTxd->pMBuf = pMessage;
1731
1732 pTxd->TBControl = Control | BMU_OWN | sk_frag->size;
1733
1734 /*
1735 ** Do we have the last fragment?
1736 */
1737 if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) {
1738#ifdef USE_TX_COMPLETE
1739 pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF;
1740#else
1741 pTxd->TBControl |= BMU_EOF;
1742#endif
1743 pTxdFst->TBControl |= BMU_OWN | BMU_SW;
1744 }
1745 pTxdLst = pTxd;
1746 pTxd = pTxd->pNextTxd;
1747 pTxPort->TxdRingFree--;
1748 BytesSend += sk_frag->size;
1749 }
1750
1751 /*
1752 ** If previous descriptor already done, give TX start cmd
1753 */
1754 if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) {
1755 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1756 }
1757
1758 pTxPort->pTxdRingPrev = pTxdLst;
1759 pTxPort->pTxdRingHead = pTxd;
1760
1761 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1762
1763 if (pTxPort->TxdRingFree > 0) {
1764 return (BytesSend);
1765 } else {
1766 return (0);
1767 }
1768}
1769
1770/*****************************************************************************
1771 *
1772 * FreeTxDescriptors - release descriptors from the descriptor ring
1773 *
1774 * Description:
1775 * This function releases descriptors from a transmit ring if they
1776 * have been sent by the BMU.
1777 * If a descriptors is sent, it can be freed and the message can
1778 * be freed, too.
1779 * The SOFTWARE controllable bit is used to prevent running around a
1780 * completely free ring for ever. If this bit is no set in the
1781 * frame (by XmitFrame), this frame has never been sent or is
1782 * already freed.
1783 * The Tx descriptor ring lock must be held while calling this function !!!
1784 *
1785 * Returns:
1786 * none
1787 */
1788static void FreeTxDescriptors(
1789SK_AC *pAC, /* pointer to the adapter context */
1790TX_PORT *pTxPort) /* pointer to destination port structure */
1791{
1792TXD *pTxd; /* pointer to the checked descriptor */
1793TXD *pNewTail; /* pointer to 'end' of the ring */
1794SK_U32 Control; /* TBControl field of descriptor */
1795SK_U64 PhysAddr; /* address of DMA mapping */
1796
1797 pNewTail = pTxPort->pTxdRingTail;
1798 pTxd = pNewTail;
1799 /*
1800 ** loop forever; exits if BMU_SW bit not set in start frame
1801 ** or BMU_OWN bit set in any frame
1802 */
1803 while (1) {
1804 Control = pTxd->TBControl;
1805 if ((Control & BMU_SW) == 0) {
1806 /*
1807 ** software controllable bit is set in first
1808 ** fragment when given to BMU. Not set means that
1809 ** this fragment was never sent or is already
1810 ** freed ( -> ring completely free now).
1811 */
1812 pTxPort->pTxdRingTail = pTxd;
1813 netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1814 return;
1815 }
1816 if (Control & BMU_OWN) {
1817 pTxPort->pTxdRingTail = pTxd;
1818 if (pTxPort->TxdRingFree > 0) {
1819 netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1820 }
1821 return;
1822 }
1823
1824 /*
1825 ** release the DMA mapping, because until not unmapped
1826 ** this buffer is considered being under control of the
1827 ** adapter card!
1828 */
1829 PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
1830 PhysAddr |= (SK_U64) pTxd->VDataLow;
1831 pci_unmap_page(pAC->PciDev, PhysAddr,
1832 pTxd->pMBuf->len,
1833 PCI_DMA_TODEVICE);
1834
1835 if (Control & BMU_EOF)
1836 DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
1837
1838 pTxPort->TxdRingFree++;
1839 pTxd->TBControl &= ~BMU_SW;
1840 pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
1841 } /* while(forever) */
1842} /* FreeTxDescriptors */
1843
1844/*****************************************************************************
1845 *
1846 * FillRxRing - fill the receive ring with valid descriptors
1847 *
1848 * Description:
1849 * This function fills the receive ring descriptors with data
1850 * segments and makes them valid for the BMU.
1851 * The active ring is filled completely, if possible.
1852 * The non-active ring is filled only partial to save memory.
1853 *
1854 * Description of rx ring structure:
1855 * head - points to the descriptor which will be used next by the BMU
1856 * tail - points to the next descriptor to give to the BMU
1857 *
1858 * Returns: N/A
1859 */
1860static void FillRxRing(
1861SK_AC *pAC, /* pointer to the adapter context */
1862RX_PORT *pRxPort) /* ptr to port struct for which the ring
1863 should be filled */
1864{
1865unsigned long Flags;
1866
1867 spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
1868 while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
1869 if(!FillRxDescriptor(pAC, pRxPort))
1870 break;
1871 }
1872 spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
1873} /* FillRxRing */
1874
1875
1876/*****************************************************************************
1877 *
1878 * FillRxDescriptor - fill one buffer into the receive ring
1879 *
1880 * Description:
1881 * The function allocates a new receive buffer and
1882 * puts it into the next descriptor.
1883 *
1884 * Returns:
1885 * SK_TRUE - a buffer was added to the ring
1886 * SK_FALSE - a buffer could not be added
1887 */
1888static SK_BOOL FillRxDescriptor(
1889SK_AC *pAC, /* pointer to the adapter context struct */
1890RX_PORT *pRxPort) /* ptr to port struct of ring to fill */
1891{
1892struct sk_buff *pMsgBlock; /* pointer to a new message block */
1893RXD *pRxd; /* the rxd to fill */
1894SK_U16 Length; /* data fragment length */
1895SK_U64 PhysAddr; /* physical address of a rx buffer */
1896
1897 pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
1898 if (pMsgBlock == NULL) {
1899 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1900 SK_DBGCAT_DRV_ENTRY,
1901 ("%s: Allocation of rx buffer failed !\n",
1902 pAC->dev[pRxPort->PortIndex]->name));
1903 SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
1904 return(SK_FALSE);
1905 }
1906 skb_reserve(pMsgBlock, 2); /* to align IP frames */
1907 /* skb allocated ok, so add buffer */
1908 pRxd = pRxPort->pRxdRingTail;
1909 pRxPort->pRxdRingTail = pRxd->pNextRxd;
1910 pRxPort->RxdRingFree--;
1911 Length = pAC->RxBufSize;
1912 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1913 virt_to_page(pMsgBlock->data),
1914 ((unsigned long) pMsgBlock->data &
1915 ~PAGE_MASK),
1916 pAC->RxBufSize - 2,
1917 PCI_DMA_FROMDEVICE);
1918
1919 pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1920 pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1921 pRxd->pMBuf = pMsgBlock;
1922 pRxd->RBControl = BMU_OWN |
1923 BMU_STF |
1924 BMU_IRQ_EOF |
1925 BMU_TCP_CHECK |
1926 Length;
1927 return (SK_TRUE);
1928
1929} /* FillRxDescriptor */
1930
1931
1932/*****************************************************************************
1933 *
1934 * ReQueueRxBuffer - fill one buffer back into the receive ring
1935 *
1936 * Description:
1937 * Fill a given buffer back into the rx ring. The buffer
1938 * has been previously allocated and aligned, and its phys.
1939 * address calculated, so this is no more necessary.
1940 *
1941 * Returns: N/A
1942 */
1943static void ReQueueRxBuffer(
1944SK_AC *pAC, /* pointer to the adapter context struct */
1945RX_PORT *pRxPort, /* ptr to port struct of ring to fill */
1946struct sk_buff *pMsg, /* pointer to the buffer */
1947SK_U32 PhysHigh, /* phys address high dword */
1948SK_U32 PhysLow) /* phys address low dword */
1949{
1950RXD *pRxd; /* the rxd to fill */
1951SK_U16 Length; /* data fragment length */
1952
1953 pRxd = pRxPort->pRxdRingTail;
1954 pRxPort->pRxdRingTail = pRxd->pNextRxd;
1955 pRxPort->RxdRingFree--;
1956 Length = pAC->RxBufSize;
1957
1958 pRxd->VDataLow = PhysLow;
1959 pRxd->VDataHigh = PhysHigh;
1960 pRxd->pMBuf = pMsg;
1961 pRxd->RBControl = BMU_OWN |
1962 BMU_STF |
1963 BMU_IRQ_EOF |
1964 BMU_TCP_CHECK |
1965 Length;
1966 return;
1967} /* ReQueueRxBuffer */
1968
1969/*****************************************************************************
1970 *
1971 * ReceiveIrq - handle a receive IRQ
1972 *
1973 * Description:
1974 * This function is called when a receive IRQ is set.
1975 * It walks the receive descriptor ring and sends up all
1976 * frames that are complete.
1977 *
1978 * Returns: N/A
1979 */
1980static void ReceiveIrq(
1981 SK_AC *pAC, /* pointer to adapter context */
1982 RX_PORT *pRxPort, /* pointer to receive port struct */
1983 SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */
1984{
1985RXD *pRxd; /* pointer to receive descriptors */
1986SK_U32 Control; /* control field of descriptor */
1987struct sk_buff *pMsg; /* pointer to message holding frame */
1988struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */
1989int FrameLength; /* total length of received frame */
1990SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */
1991SK_EVPARA EvPara; /* an event parameter union */
1992unsigned long Flags; /* for spin lock */
1993int PortIndex = pRxPort->PortIndex;
1994unsigned int Offset;
1995unsigned int NumBytes;
1996unsigned int ForRlmt;
1997SK_BOOL IsBc;
1998SK_BOOL IsMc;
1999SK_BOOL IsBadFrame; /* Bad frame */
2000
2001SK_U32 FrameStat;
2002SK_U64 PhysAddr;
2003
2004rx_start:
2005 /* do forever; exit if BMU_OWN found */
2006 for ( pRxd = pRxPort->pRxdRingHead ;
2007 pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
2008 pRxd = pRxd->pNextRxd,
2009 pRxPort->pRxdRingHead = pRxd,
2010 pRxPort->RxdRingFree ++) {
2011
2012 /*
2013 * For a better understanding of this loop
2014 * Go through every descriptor beginning at the head
2015 * Please note: the ring might be completely received so the OWN bit
2016 * set is not a good crirteria to leave that loop.
2017 * Therefore the RingFree counter is used.
2018 * On entry of this loop pRxd is a pointer to the Rxd that needs
2019 * to be checked next.
2020 */
2021
2022 Control = pRxd->RBControl;
2023
2024 /* check if this descriptor is ready */
2025 if ((Control & BMU_OWN) != 0) {
2026 /* this descriptor is not yet ready */
2027 /* This is the usual end of the loop */
2028 /* We don't need to start the ring again */
2029 FillRxRing(pAC, pRxPort);
2030 return;
2031 }
2032 pAC->DynIrqModInfo.NbrProcessedDescr++;
2033
2034 /* get length of frame and check it */
2035 FrameLength = Control & BMU_BBC;
2036 if (FrameLength > pAC->RxBufSize) {
2037 goto rx_failed;
2038 }
2039
2040 /* check for STF and EOF */
2041 if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) {
2042 goto rx_failed;
2043 }
2044
2045 /* here we have a complete frame in the ring */
2046 pMsg = pRxd->pMBuf;
2047
2048 FrameStat = pRxd->FrameStat;
2049
2050 /* check for frame length mismatch */
2051#define XMR_FS_LEN_SHIFT 18
2052#define GMR_FS_LEN_SHIFT 16
2053 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2054 if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
2055 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2056 SK_DBGCAT_DRV_RX_PROGRESS,
2057 ("skge: Frame length mismatch (%u/%u).\n",
2058 FrameLength,
2059 (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2060 goto rx_failed;
2061 }
2062 }
2063 else {
2064 if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
2065 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2066 SK_DBGCAT_DRV_RX_PROGRESS,
2067 ("skge: Frame length mismatch (%u/%u).\n",
2068 FrameLength,
2069 (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2070 goto rx_failed;
2071 }
2072 }
2073
2074 /* Set Rx Status */
2075 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2076 IsBc = (FrameStat & XMR_FS_BC) != 0;
2077 IsMc = (FrameStat & XMR_FS_MC) != 0;
2078 IsBadFrame = (FrameStat &
2079 (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
2080 } else {
2081 IsBc = (FrameStat & GMR_FS_BC) != 0;
2082 IsMc = (FrameStat & GMR_FS_MC) != 0;
2083 IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
2084 ((FrameStat & GMR_FS_RX_OK) == 0));
2085 }
2086
2087 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2088 ("Received frame of length %d on port %d\n",
2089 FrameLength, PortIndex));
2090 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2091 ("Number of free rx descriptors: %d\n",
2092 pRxPort->RxdRingFree));
2093/* DumpMsg(pMsg, "Rx"); */
2094
2095 if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
2096#if 0
2097 (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
2098#endif
2099 /* there is a receive error in this frame */
2100 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2101 SK_DBGCAT_DRV_RX_PROGRESS,
2102 ("skge: Error in received frame, dropped!\n"
2103 "Control: %x\nRxStat: %x\n",
2104 Control, FrameStat));
2105
2106 ReQueueRxBuffer(pAC, pRxPort, pMsg,
2107 pRxd->VDataHigh, pRxd->VDataLow);
2108
2109 continue;
2110 }
2111
2112 /*
2113 * if short frame then copy data to reduce memory waste
2114 */
2115 if ((FrameLength < SK_COPY_THRESHOLD) &&
2116 ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
2117 /*
2118 * Short frame detected and allocation successfull
2119 */
2120 /* use new skb and copy data */
2121 skb_reserve(pNewMsg, 2);
2122 skb_put(pNewMsg, FrameLength);
2123 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2124 PhysAddr |= (SK_U64) pRxd->VDataLow;
2125
2126 pci_dma_sync_single_for_cpu(pAC->PciDev,
2127 (dma_addr_t) PhysAddr,
2128 FrameLength,
2129 PCI_DMA_FROMDEVICE);
2130 skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength);
2131
2132 pci_dma_sync_single_for_device(pAC->PciDev,
2133 (dma_addr_t) PhysAddr,
2134 FrameLength,
2135 PCI_DMA_FROMDEVICE);
2136 ReQueueRxBuffer(pAC, pRxPort, pMsg,
2137 pRxd->VDataHigh, pRxd->VDataLow);
2138
2139 pMsg = pNewMsg;
2140
2141 }
2142 else {
2143 /*
2144 * if large frame, or SKB allocation failed, pass
2145 * the SKB directly to the networking
2146 */
2147
2148 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2149 PhysAddr |= (SK_U64) pRxd->VDataLow;
2150
2151 /* release the DMA mapping */
2152 pci_unmap_single(pAC->PciDev,
2153 PhysAddr,
2154 pAC->RxBufSize - 2,
2155 PCI_DMA_FROMDEVICE);
2156
2157 /* set length in message */
2158 skb_put(pMsg, FrameLength);
2159 } /* frame > SK_COPY_TRESHOLD */
2160
2161#ifdef USE_SK_RX_CHECKSUM
2162 pMsg->csum = pRxd->TcpSums & 0xffff;
2163 pMsg->ip_summed = CHECKSUM_COMPLETE;
2164#else
2165 pMsg->ip_summed = CHECKSUM_NONE;
2166#endif
2167
2168 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
2169 ForRlmt = SK_RLMT_RX_PROTOCOL;
2170#if 0
2171 IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
2172#endif
2173 SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
2174 IsBc, &Offset, &NumBytes);
2175 if (NumBytes != 0) {
2176#if 0
2177 IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
2178#endif
2179 SK_RLMT_LOOKAHEAD(pAC, PortIndex,
2180 &pMsg->data[Offset],
2181 IsBc, IsMc, &ForRlmt);
2182 }
2183 if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
2184 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
2185 /* send up only frames from active port */
2186 if ((PortIndex == pAC->ActivePort) ||
2187 (pAC->RlmtNets == 2)) {
2188 /* frame for upper layer */
2189 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
2190#ifdef xDEBUG
2191 DumpMsg(pMsg, "Rx");
2192#endif
2193 SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
2194 FrameLength, pRxPort->PortIndex);
2195
2196 pMsg->protocol = eth_type_trans(pMsg,
2197 pAC->dev[pRxPort->PortIndex]);
2198 netif_rx(pMsg);
2199 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2200 }
2201 else {
2202 /* drop frame */
2203 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2204 SK_DBGCAT_DRV_RX_PROGRESS,
2205 ("D"));
2206 DEV_KFREE_SKB(pMsg);
2207 }
2208
2209 } /* if not for rlmt */
2210 else {
2211 /* packet for rlmt */
2212 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2213 SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
2214 pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
2215 pAC->IoBase, FrameLength);
2216 if (pRlmtMbuf != NULL) {
2217 pRlmtMbuf->pNext = NULL;
2218 pRlmtMbuf->Length = FrameLength;
2219 pRlmtMbuf->PortIdx = PortIndex;
2220 EvPara.pParaPtr = pRlmtMbuf;
2221 memcpy((char*)(pRlmtMbuf->pData),
2222 (char*)(pMsg->data),
2223 FrameLength);
2224
2225 /* SlowPathLock needed? */
2226 if (SlowPathLock == SK_TRUE) {
2227 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2228 SkEventQueue(pAC, SKGE_RLMT,
2229 SK_RLMT_PACKET_RECEIVED,
2230 EvPara);
2231 pAC->CheckQueue = SK_TRUE;
2232 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2233 } else {
2234 SkEventQueue(pAC, SKGE_RLMT,
2235 SK_RLMT_PACKET_RECEIVED,
2236 EvPara);
2237 pAC->CheckQueue = SK_TRUE;
2238 }
2239
2240 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2241 SK_DBGCAT_DRV_RX_PROGRESS,
2242 ("Q"));
2243 }
2244 if ((pAC->dev[pRxPort->PortIndex]->flags &
2245 (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
2246 (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
2247 SK_RLMT_RX_PROTOCOL) {
2248 pMsg->protocol = eth_type_trans(pMsg,
2249 pAC->dev[pRxPort->PortIndex]);
2250 netif_rx(pMsg);
2251 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2252 }
2253 else {
2254 DEV_KFREE_SKB(pMsg);
2255 }
2256
2257 } /* if packet for rlmt */
2258 } /* for ... scanning the RXD ring */
2259
2260 /* RXD ring is empty -> fill and restart */
2261 FillRxRing(pAC, pRxPort);
2262 /* do not start if called from Close */
2263 if (pAC->BoardLevel > SK_INIT_DATA) {
2264 ClearAndStartRx(pAC, PortIndex);
2265 }
2266 return;
2267
2268rx_failed:
2269 /* remove error frame */
2270 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
2271 ("Schrottdescriptor, length: 0x%x\n", FrameLength));
2272
2273 /* release the DMA mapping */
2274
2275 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2276 PhysAddr |= (SK_U64) pRxd->VDataLow;
2277 pci_unmap_page(pAC->PciDev,
2278 PhysAddr,
2279 pAC->RxBufSize - 2,
2280 PCI_DMA_FROMDEVICE);
2281 DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
2282 pRxd->pMBuf = NULL;
2283 pRxPort->RxdRingFree++;
2284 pRxPort->pRxdRingHead = pRxd->pNextRxd;
2285 goto rx_start;
2286
2287} /* ReceiveIrq */
2288
2289
2290/*****************************************************************************
2291 *
2292 * ClearAndStartRx - give a start receive command to BMU, clear IRQ
2293 *
2294 * Description:
2295 * This function sends a start command and a clear interrupt
2296 * command for one receive queue to the BMU.
2297 *
2298 * Returns: N/A
2299 * none
2300 */
2301static void ClearAndStartRx(
2302SK_AC *pAC, /* pointer to the adapter context */
2303int PortIndex) /* index of the receive port (XMAC) */
2304{
2305 SK_OUT8(pAC->IoBase,
2306 RxQueueAddr[PortIndex]+Q_CSR,
2307 CSR_START | CSR_IRQ_CL_F);
2308} /* ClearAndStartRx */
2309
2310
2311/*****************************************************************************
2312 *
2313 * ClearTxIrq - give a clear transmit IRQ command to BMU
2314 *
2315 * Description:
2316 * This function sends a clear tx IRQ command for one
2317 * transmit queue to the BMU.
2318 *
2319 * Returns: N/A
2320 */
2321static void ClearTxIrq(
2322SK_AC *pAC, /* pointer to the adapter context */
2323int PortIndex, /* index of the transmit port (XMAC) */
2324int Prio) /* priority or normal queue */
2325{
2326 SK_OUT8(pAC->IoBase,
2327 TxQueueAddr[PortIndex][Prio]+Q_CSR,
2328 CSR_IRQ_CL_F);
2329} /* ClearTxIrq */
2330
2331
2332/*****************************************************************************
2333 *
2334 * ClearRxRing - remove all buffers from the receive ring
2335 *
2336 * Description:
2337 * This function removes all receive buffers from the ring.
2338 * The receive BMU must be stopped before calling this function.
2339 *
2340 * Returns: N/A
2341 */
2342static void ClearRxRing(
2343SK_AC *pAC, /* pointer to adapter context */
2344RX_PORT *pRxPort) /* pointer to rx port struct */
2345{
2346RXD *pRxd; /* pointer to the current descriptor */
2347unsigned long Flags;
2348SK_U64 PhysAddr;
2349
2350 if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
2351 return;
2352 }
2353 spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
2354 pRxd = pRxPort->pRxdRingHead;
2355 do {
2356 if (pRxd->pMBuf != NULL) {
2357
2358 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2359 PhysAddr |= (SK_U64) pRxd->VDataLow;
2360 pci_unmap_page(pAC->PciDev,
2361 PhysAddr,
2362 pAC->RxBufSize - 2,
2363 PCI_DMA_FROMDEVICE);
2364 DEV_KFREE_SKB(pRxd->pMBuf);
2365 pRxd->pMBuf = NULL;
2366 }
2367 pRxd->RBControl &= BMU_OWN;
2368 pRxd = pRxd->pNextRxd;
2369 pRxPort->RxdRingFree++;
2370 } while (pRxd != pRxPort->pRxdRingTail);
2371 pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
2372 spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
2373} /* ClearRxRing */
2374
2375/*****************************************************************************
2376 *
2377 * ClearTxRing - remove all buffers from the transmit ring
2378 *
2379 * Description:
2380 * This function removes all transmit buffers from the ring.
2381 * The transmit BMU must be stopped before calling this function
2382 * and transmitting at the upper level must be disabled.
2383 * The BMU own bit of all descriptors is cleared, the rest is
2384 * done by calling FreeTxDescriptors.
2385 *
2386 * Returns: N/A
2387 */
2388static void ClearTxRing(
2389SK_AC *pAC, /* pointer to adapter context */
2390TX_PORT *pTxPort) /* pointer to tx prt struct */
2391{
2392TXD *pTxd; /* pointer to the current descriptor */
2393int i;
2394unsigned long Flags;
2395
2396 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
2397 pTxd = pTxPort->pTxdRingHead;
2398 for (i=0; i<pAC->TxDescrPerRing; i++) {
2399 pTxd->TBControl &= ~BMU_OWN;
2400 pTxd = pTxd->pNextTxd;
2401 }
2402 FreeTxDescriptors(pAC, pTxPort);
2403 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
2404} /* ClearTxRing */
2405
2406/*****************************************************************************
2407 *
2408 * SkGeSetMacAddr - Set the hardware MAC address
2409 *
2410 * Description:
2411 * This function sets the MAC address used by the adapter.
2412 *
2413 * Returns:
2414 * 0, if everything is ok
2415 * !=0, on error
2416 */
2417static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
2418{
2419
2420DEV_NET *pNet = netdev_priv(dev);
2421SK_AC *pAC = pNet->pAC;
2422
2423struct sockaddr *addr = p;
2424unsigned long Flags;
2425
2426 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2427 ("SkGeSetMacAddr starts now...\n"));
2428 if(netif_running(dev))
2429 return -EBUSY;
2430
2431 memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
2432
2433 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2434
2435 if (pAC->RlmtNets == 2)
2436 SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
2437 (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2438 else
2439 SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
2440 (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2441
2442
2443
2444 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2445 return 0;
2446} /* SkGeSetMacAddr */
2447
2448
2449/*****************************************************************************
2450 *
2451 * SkGeSetRxMode - set receive mode
2452 *
2453 * Description:
2454 * This function sets the receive mode of an adapter. The adapter
2455 * supports promiscuous mode, allmulticast mode and a number of
2456 * multicast addresses. If more multicast addresses the available
2457 * are selected, a hash function in the hardware is used.
2458 *
2459 * Returns:
2460 * 0, if everything is ok
2461 * !=0, on error
2462 */
2463static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
2464{
2465
2466DEV_NET *pNet;
2467SK_AC *pAC;
2468
2469struct dev_mc_list *pMcList;
2470int i;
2471int PortIdx;
2472unsigned long Flags;
2473
2474 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2475 ("SkGeSetRxMode starts now... "));
2476
2477 pNet = netdev_priv(dev);
2478 pAC = pNet->pAC;
2479 if (pAC->RlmtNets == 1)
2480 PortIdx = pAC->ActivePort;
2481 else
2482 PortIdx = pNet->NetNr;
2483
2484 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2485 if (dev->flags & IFF_PROMISC) {
2486 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2487 ("PROMISCUOUS mode\n"));
2488 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2489 SK_PROM_MODE_LLC);
2490 } else if (dev->flags & IFF_ALLMULTI) {
2491 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2492 ("ALLMULTI mode\n"));
2493 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2494 SK_PROM_MODE_ALL_MC);
2495 } else {
2496 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2497 SK_PROM_MODE_NONE);
2498 SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
2499
2500 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2501 ("Number of MC entries: %d ", dev->mc_count));
2502
2503 pMcList = dev->mc_list;
2504 for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
2505 SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
2506 (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
2507 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
2508 ("%02x:%02x:%02x:%02x:%02x:%02x\n",
2509 pMcList->dmi_addr[0],
2510 pMcList->dmi_addr[1],
2511 pMcList->dmi_addr[2],
2512 pMcList->dmi_addr[3],
2513 pMcList->dmi_addr[4],
2514 pMcList->dmi_addr[5]));
2515 }
2516 SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
2517 }
2518 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2519
2520 return;
2521} /* SkGeSetRxMode */
2522
2523
2524/*****************************************************************************
2525 *
2526 * SkGeChangeMtu - set the MTU to another value
2527 *
2528 * Description:
2529 * This function sets is called whenever the MTU size is changed
2530 * (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
2531 * ethernet MTU size, long frame support is activated.
2532 *
2533 * Returns:
2534 * 0, if everything is ok
2535 * !=0, on error
2536 */
2537static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
2538{
2539DEV_NET *pNet;
2540struct net_device *pOtherDev;
2541SK_AC *pAC;
2542unsigned long Flags;
2543int i;
2544SK_EVPARA EvPara;
2545
2546 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2547 ("SkGeChangeMtu starts now...\n"));
2548
2549 pNet = netdev_priv(dev);
2550 pAC = pNet->pAC;
2551
2552 if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
2553 return -EINVAL;
2554 }
2555
2556 if(pAC->BoardLevel != SK_INIT_RUN) {
2557 return -EINVAL;
2558 }
2559
2560#ifdef SK_DIAG_SUPPORT
2561 if (pAC->DiagModeActive == DIAG_ACTIVE) {
2562 if (pAC->DiagFlowCtrl == SK_FALSE) {
2563 return -1; /* still in use, deny any actions of MTU */
2564 } else {
2565 pAC->DiagFlowCtrl = SK_FALSE;
2566 }
2567 }
2568#endif
2569
2570 pOtherDev = pAC->dev[1 - pNet->NetNr];
2571
2572 if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
2573 && (NewMtu <= 1500))
2574 return 0;
2575
2576 pAC->RxBufSize = NewMtu + 32;
2577 dev->mtu = NewMtu;
2578
2579 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2580 ("New MTU: %d\n", NewMtu));
2581
2582 /*
2583 ** Prevent any reconfiguration while changing the MTU
2584 ** by disabling any interrupts
2585 */
2586 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
2587 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2588
2589 /*
2590 ** Notify RLMT that any ports are to be stopped
2591 */
2592 EvPara.Para32[0] = 0;
2593 EvPara.Para32[1] = -1;
2594 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2595 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2596 EvPara.Para32[0] = 1;
2597 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2598 } else {
2599 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2600 }
2601
2602 /*
2603 ** After calling the SkEventDispatcher(), RLMT is aware about
2604 ** the stopped ports -> configuration can take place!
2605 */
2606 SkEventDispatcher(pAC, pAC->IoBase);
2607
2608 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2609 spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2610 netif_stop_queue(pAC->dev[i]);
2611
2612 }
2613
2614 /*
2615 ** Depending on the desired MTU size change, a different number of
2616 ** RX buffers need to be allocated
2617 */
2618 if (NewMtu > 1500) {
2619 /*
2620 ** Use less rx buffers
2621 */
2622 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2623 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2624 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2625 (pAC->RxDescrPerRing / 4);
2626 } else {
2627 if (i == pAC->ActivePort) {
2628 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2629 (pAC->RxDescrPerRing / 4);
2630 } else {
2631 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2632 (pAC->RxDescrPerRing / 10);
2633 }
2634 }
2635 }
2636 } else {
2637 /*
2638 ** Use the normal amount of rx buffers
2639 */
2640 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2641 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2642 pAC->RxPort[i].RxFillLimit = 1;
2643 } else {
2644 if (i == pAC->ActivePort) {
2645 pAC->RxPort[i].RxFillLimit = 1;
2646 } else {
2647 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2648 (pAC->RxDescrPerRing / 4);
2649 }
2650 }
2651 }
2652 }
2653
2654 SkGeDeInit(pAC, pAC->IoBase);
2655
2656 /*
2657 ** enable/disable hardware support for long frames
2658 */
2659 if (NewMtu > 1500) {
2660// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
2661 pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
2662 } else {
2663 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2664 pAC->GIni.GIPortUsage = SK_MUL_LINK;
2665 } else {
2666 pAC->GIni.GIPortUsage = SK_RED_LINK;
2667 }
2668 }
2669
2670 SkGeInit( pAC, pAC->IoBase, SK_INIT_IO);
2671 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
2672 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
2673 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
2674 SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
2675 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
2676 SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
2677
2678 /*
2679 ** tschilling:
2680 ** Speed and others are set back to default in level 1 init!
2681 */
2682 GetConfiguration(pAC);
2683
2684 SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN);
2685 SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN);
2686 SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
2687 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
2688 SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
2689 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
2690 SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
2691
2692 /*
2693 ** clear and reinit the rx rings here
2694 */
2695 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2696 ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
2697 ClearRxRing(pAC, &pAC->RxPort[i]);
2698 FillRxRing(pAC, &pAC->RxPort[i]);
2699
2700 /*
2701 ** Enable transmit descriptor polling
2702 */
2703 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
2704 FillRxRing(pAC, &pAC->RxPort[i]);
2705 };
2706
2707 SkGeYellowLED(pAC, pAC->IoBase, 1);
2708 SkDimEnableModerationIfNeeded(pAC);
2709 SkDimDisplayModerationSettings(pAC);
2710
2711 netif_start_queue(pAC->dev[pNet->PortNr]);
2712 for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
2713 spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2714 }
2715
2716 /*
2717 ** Enable Interrupts again
2718 */
2719 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
2720 SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
2721
2722 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2723 SkEventDispatcher(pAC, pAC->IoBase);
2724
2725 /*
2726 ** Notify RLMT about the changing and restarting one (or more) ports
2727 */
2728 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2729 EvPara.Para32[0] = pAC->RlmtNets;
2730 EvPara.Para32[1] = -1;
2731 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
2732 EvPara.Para32[0] = pNet->PortNr;
2733 EvPara.Para32[1] = -1;
2734 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2735
2736 if (netif_running(pOtherDev)) {
2737 DEV_NET *pOtherNet = netdev_priv(pOtherDev);
2738 EvPara.Para32[0] = pOtherNet->PortNr;
2739 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2740 }
2741 } else {
2742 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2743 }
2744
2745 SkEventDispatcher(pAC, pAC->IoBase);
2746 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2747
2748 /*
2749 ** While testing this driver with latest kernel 2.5 (2.5.70), it
2750 ** seems as if upper layers have a problem to handle a successful
2751 ** return value of '0'. If such a zero is returned, the complete
2752 ** system hangs for several minutes (!), which is in acceptable.
2753 **
2754 ** Currently it is not clear, what the exact reason for this problem
2755 ** is. The implemented workaround for 2.5 is to return the desired
2756 ** new MTU size if all needed changes for the new MTU size where
2757 ** performed. In kernels 2.2 and 2.4, a zero value is returned,
2758 ** which indicates the successful change of the mtu-size.
2759 */
2760 return NewMtu;
2761
2762} /* SkGeChangeMtu */
2763
2764
2765/*****************************************************************************
2766 *
2767 * SkGeStats - return ethernet device statistics
2768 *
2769 * Description:
2770 * This function return statistic data about the ethernet device
2771 * to the operating system.
2772 *
2773 * Returns:
2774 * pointer to the statistic structure.
2775 */
2776static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
2777{
2778DEV_NET *pNet = netdev_priv(dev);
2779SK_AC *pAC = pNet->pAC;
2780SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */
2781SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */
2782SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */
2783unsigned int Size; /* size of pnmi struct */
2784unsigned long Flags; /* for spin lock */
2785
2786 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2787 ("SkGeStats starts now...\n"));
2788 pPnmiStruct = &pAC->PnmiStruct;
2789
2790#ifdef SK_DIAG_SUPPORT
2791 if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
2792 (pAC->BoardLevel == SK_INIT_RUN)) {
2793#endif
2794 SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
2795 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2796 Size = SK_PNMI_STRUCT_SIZE;
2797 SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
2798 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2799#ifdef SK_DIAG_SUPPORT
2800 }
2801#endif
2802
2803 pPnmiStat = &pPnmiStruct->Stat[0];
2804 pPnmiConf = &pPnmiStruct->Conf[0];
2805
2806 pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
2807 pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
2808 pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
2809 pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
2810
2811 if (dev->mtu <= 1500) {
2812 pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
2813 } else {
2814 pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
2815 pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
2816 }
2817
2818
2819 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
2820 pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
2821
2822 pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2823 pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
2824 pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
2825 pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
2826 pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2827
2828 /* detailed rx_errors: */
2829 pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
2830 pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2831 pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
2832 pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
2833 pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2834 pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
2835
2836 /* detailed tx_errors */
2837 pAC->stats.tx_aborted_errors = (SK_U32) 0;
2838 pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2839 pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
2840 pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2841 pAC->stats.tx_window_errors = (SK_U32) 0;
2842
2843 return(&pAC->stats);
2844} /* SkGeStats */
2845
2846/*
2847 * Basic MII register access
2848 */
2849static int SkGeMiiIoctl(struct net_device *dev,
2850 struct mii_ioctl_data *data, int cmd)
2851{
2852 DEV_NET *pNet = netdev_priv(dev);
2853 SK_AC *pAC = pNet->pAC;
2854 SK_IOC IoC = pAC->IoBase;
2855 int Port = pNet->PortNr;
2856 SK_GEPORT *pPrt = &pAC->GIni.GP[Port];
2857 unsigned long Flags;
2858 int err = 0;
2859 int reg = data->reg_num & 0x1f;
2860 SK_U16 val = data->val_in;
2861
2862 if (!netif_running(dev))
2863 return -ENODEV; /* Phy still in reset */
2864
2865 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2866 switch(cmd) {
2867 case SIOCGMIIPHY:
2868 data->phy_id = pPrt->PhyAddr;
2869
2870 /* fallthru */
2871 case SIOCGMIIREG:
2872 if (pAC->GIni.GIGenesis)
2873 SkXmPhyRead(pAC, IoC, Port, reg, &val);
2874 else
2875 SkGmPhyRead(pAC, IoC, Port, reg, &val);
2876
2877 data->val_out = val;
2878 break;
2879
2880 case SIOCSMIIREG:
2881 if (!capable(CAP_NET_ADMIN))
2882 err = -EPERM;
2883
2884 else if (pAC->GIni.GIGenesis)
2885 SkXmPhyWrite(pAC, IoC, Port, reg, val);
2886 else
2887 SkGmPhyWrite(pAC, IoC, Port, reg, val);
2888 break;
2889 default:
2890 err = -EOPNOTSUPP;
2891 }
2892 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2893 return err;
2894}
2895
2896
2897/*****************************************************************************
2898 *
2899 * SkGeIoctl - IO-control function
2900 *
2901 * Description:
2902 * This function is called if an ioctl is issued on the device.
2903 * There are three subfunction for reading, writing and test-writing
2904 * the private MIB data structure (useful for SysKonnect-internal tools).
2905 *
2906 * Returns:
2907 * 0, if everything is ok
2908 * !=0, on error
2909 */
2910static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
2911{
2912DEV_NET *pNet;
2913SK_AC *pAC;
2914void *pMemBuf;
2915struct pci_dev *pdev = NULL;
2916SK_GE_IOCTL Ioctl;
2917unsigned int Err = 0;
2918int Size = 0;
2919int Ret = 0;
2920unsigned int Length = 0;
2921int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
2922
2923 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2924 ("SkGeIoctl starts now...\n"));
2925
2926 pNet = netdev_priv(dev);
2927 pAC = pNet->pAC;
2928
2929 if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG)
2930 return SkGeMiiIoctl(dev, if_mii(rq), cmd);
2931
2932 if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
2933 return -EFAULT;
2934 }
2935
2936 switch(cmd) {
2937 case SK_IOCTL_SETMIB:
2938 case SK_IOCTL_PRESETMIB:
2939 if (!capable(CAP_NET_ADMIN)) return -EPERM;
2940 case SK_IOCTL_GETMIB:
2941 if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
2942 Ioctl.Len<sizeof(pAC->PnmiStruct)?
2943 Ioctl.Len : sizeof(pAC->PnmiStruct))) {
2944 return -EFAULT;
2945 }
2946 Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
2947 if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
2948 Ioctl.Len<Size? Ioctl.Len : Size)) {
2949 return -EFAULT;
2950 }
2951 Ioctl.Len = Size;
2952 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
2953 return -EFAULT;
2954 }
2955 break;
2956 case SK_IOCTL_GEN:
2957 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
2958 Length = Ioctl.Len;
2959 } else {
2960 Length = sizeof(pAC->PnmiStruct) + HeaderLength;
2961 }
2962 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
2963 return -ENOMEM;
2964 }
2965 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
2966 Err = -EFAULT;
2967 goto fault_gen;
2968 }
2969 if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
2970 Err = -EFAULT;
2971 goto fault_gen;
2972 }
2973 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
2974 Err = -EFAULT;
2975 goto fault_gen;
2976 }
2977 Ioctl.Len = Length;
2978 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
2979 Err = -EFAULT;
2980 goto fault_gen;
2981 }
2982fault_gen:
2983 kfree(pMemBuf); /* cleanup everything */
2984 break;
2985#ifdef SK_DIAG_SUPPORT
2986 case SK_IOCTL_DIAG:
2987 if (!capable(CAP_NET_ADMIN)) return -EPERM;
2988 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
2989 Length = Ioctl.Len;
2990 } else {
2991 Length = sizeof(pAC->PnmiStruct) + HeaderLength;
2992 }
2993 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
2994 return -ENOMEM;
2995 }
2996 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
2997 Err = -EFAULT;
2998 goto fault_diag;
2999 }
3000 pdev = pAC->PciDev;
3001 Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */
3002 /*
3003 ** While coding this new IOCTL interface, only a few lines of code
3004 ** are to to be added. Therefore no dedicated function has been
3005 ** added. If more functionality is added, a separate function
3006 ** should be used...
3007 */
3008 * ((SK_U32 *)pMemBuf) = 0;
3009 * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
3010 * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
3011 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
3012 Err = -EFAULT;
3013 goto fault_diag;
3014 }
3015 Ioctl.Len = Length;
3016 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3017 Err = -EFAULT;
3018 goto fault_diag;
3019 }
3020fault_diag:
3021 kfree(pMemBuf); /* cleanup everything */
3022 break;
3023#endif
3024 default:
3025 Err = -EOPNOTSUPP;
3026 }
3027
3028 return(Err);
3029
3030} /* SkGeIoctl */
3031
3032
3033/*****************************************************************************
3034 *
3035 * SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
3036 *
3037 * Description:
3038 * This function reads/writes the MIB data using PNMI (Private Network
3039 * Management Interface).
3040 * The destination for the data must be provided with the
3041 * ioctl call and is given to the driver in the form of
3042 * a user space address.
3043 * Copying from the user-provided data area into kernel messages
3044 * and back is done by copy_from_user and copy_to_user calls in
3045 * SkGeIoctl.
3046 *
3047 * Returns:
3048 * returned size from PNMI call
3049 */
3050static int SkGeIocMib(
3051DEV_NET *pNet, /* pointer to the adapter context */
3052unsigned int Size, /* length of ioctl data */
3053int mode) /* flag for set/preset */
3054{
3055unsigned long Flags; /* for spin lock */
3056SK_AC *pAC;
3057
3058 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3059 ("SkGeIocMib starts now...\n"));
3060 pAC = pNet->pAC;
3061 /* access MIB */
3062 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3063 switch(mode) {
3064 case SK_IOCTL_GETMIB:
3065 SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3066 pNet->NetNr);
3067 break;
3068 case SK_IOCTL_PRESETMIB:
3069 SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3070 pNet->NetNr);
3071 break;
3072 case SK_IOCTL_SETMIB:
3073 SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3074 pNet->NetNr);
3075 break;
3076 default:
3077 break;
3078 }
3079 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3080 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3081 ("MIB data access succeeded\n"));
3082 return (Size);
3083} /* SkGeIocMib */
3084
3085
3086/*****************************************************************************
3087 *
3088 * GetConfiguration - read configuration information
3089 *
3090 * Description:
3091 * This function reads per-adapter configuration information from
3092 * the options provided on the command line.
3093 *
3094 * Returns:
3095 * none
3096 */
3097static void GetConfiguration(
3098SK_AC *pAC) /* pointer to the adapter context structure */
3099{
3100SK_I32 Port; /* preferred port */
3101SK_BOOL AutoSet;
3102SK_BOOL DupSet;
3103int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */
3104int AutoNeg = 1; /* autoneg off (0) or on (1) */
3105int DuplexCap = 0; /* 0=both,1=full,2=half */
3106int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */
3107int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */
3108
3109SK_BOOL IsConTypeDefined = SK_TRUE;
3110SK_BOOL IsLinkSpeedDefined = SK_TRUE;
3111SK_BOOL IsFlowCtrlDefined = SK_TRUE;
3112SK_BOOL IsRoleDefined = SK_TRUE;
3113SK_BOOL IsModeDefined = SK_TRUE;
3114/*
3115 * The two parameters AutoNeg. and DuplexCap. map to one configuration
3116 * parameter. The mapping is described by this table:
3117 * DuplexCap -> | both | full | half |
3118 * AutoNeg | | | |
3119 * -----------------------------------------------------------------
3120 * Off | illegal | Full | Half |
3121 * -----------------------------------------------------------------
3122 * On | AutoBoth | AutoFull | AutoHalf |
3123 * -----------------------------------------------------------------
3124 * Sense | AutoSense | AutoSense | AutoSense |
3125 */
3126int Capabilities[3][3] =
3127 { { -1, SK_LMODE_FULL , SK_LMODE_HALF },
3128 {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
3129 {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
3130
3131#define DC_BOTH 0
3132#define DC_FULL 1
3133#define DC_HALF 2
3134#define AN_OFF 0
3135#define AN_ON 1
3136#define AN_SENS 2
3137#define M_CurrPort pAC->GIni.GP[Port]
3138
3139
3140 /*
3141 ** Set the default values first for both ports!
3142 */
3143 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3144 M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3145 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3146 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3147 M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
3148 }
3149
3150 /*
3151 ** Check merged parameter ConType. If it has not been used,
3152 ** verify any other parameter (e.g. AutoNeg) and use default values.
3153 **
3154 ** Stating both ConType and other lowlevel link parameters is also
3155 ** possible. If this is the case, the passed ConType-parameter is
3156 ** overwritten by the lowlevel link parameter.
3157 **
3158 ** The following settings are used for a merged ConType-parameter:
3159 **
3160 ** ConType DupCap AutoNeg FlowCtrl Role Speed
3161 ** ------- ------ ------- -------- ---------- -----
3162 ** Auto Both On SymOrRem Auto Auto
3163 ** 100FD Full Off None <ignored> 100
3164 ** 100HD Half Off None <ignored> 100
3165 ** 10FD Full Off None <ignored> 10
3166 ** 10HD Half Off None <ignored> 10
3167 **
3168 ** This ConType parameter is used for all ports of the adapter!
3169 */
3170 if ( (ConType != NULL) &&
3171 (pAC->Index < SK_MAX_CARD_PARAM) &&
3172 (ConType[pAC->Index] != NULL) ) {
3173
3174 /* Check chipset family */
3175 if ((!pAC->ChipsetType) &&
3176 (strcmp(ConType[pAC->Index],"Auto")!=0) &&
3177 (strcmp(ConType[pAC->Index],"")!=0)) {
3178 /* Set the speed parameter back */
3179 printk("sk98lin: Illegal value \"%s\" "
3180 "for ConType."
3181 " Using Auto.\n",
3182 ConType[pAC->Index]);
3183
3184 sprintf(ConType[pAC->Index], "Auto");
3185 }
3186
3187 if (strcmp(ConType[pAC->Index],"")==0) {
3188 IsConTypeDefined = SK_FALSE; /* No ConType defined */
3189 } else if (strcmp(ConType[pAC->Index],"Auto")==0) {
3190 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3191 M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3192 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3193 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3194 M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
3195 }
3196 } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
3197 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3198 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3199 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3200 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3201 M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
3202 }
3203 } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
3204 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3205 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3206 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3207 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3208 M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
3209 }
3210 } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
3211 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3212 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3213 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3214 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3215 M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
3216 }
3217 } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
3218 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3219 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3220 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3221 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3222 M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
3223 }
3224 } else {
3225 printk("sk98lin: Illegal value \"%s\" for ConType\n",
3226 ConType[pAC->Index]);
3227 IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
3228 }
3229 } else {
3230 IsConTypeDefined = SK_FALSE; /* No ConType defined */
3231 }
3232
3233 /*
3234 ** Parse any parameter settings for port A:
3235 ** a) any LinkSpeed stated?
3236 */
3237 if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3238 Speed_A[pAC->Index] != NULL) {
3239 if (strcmp(Speed_A[pAC->Index],"")==0) {
3240 IsLinkSpeedDefined = SK_FALSE;
3241 } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
3242 LinkSpeed = SK_LSPEED_AUTO;
3243 } else if (strcmp(Speed_A[pAC->Index],"10")==0) {
3244 LinkSpeed = SK_LSPEED_10MBPS;
3245 } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
3246 LinkSpeed = SK_LSPEED_100MBPS;
3247 } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
3248 LinkSpeed = SK_LSPEED_1000MBPS;
3249 } else {
3250 printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
3251 Speed_A[pAC->Index]);
3252 IsLinkSpeedDefined = SK_FALSE;
3253 }
3254 } else {
3255 IsLinkSpeedDefined = SK_FALSE;
3256 }
3257
3258 /*
3259 ** Check speed parameter:
3260 ** Only copper type adapter and GE V2 cards
3261 */
3262 if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3263 ((LinkSpeed != SK_LSPEED_AUTO) &&
3264 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3265 printk("sk98lin: Illegal value for Speed_A. "
3266 "Not a copper card or GE V2 card\n Using "
3267 "speed 1000\n");
3268 LinkSpeed = SK_LSPEED_1000MBPS;
3269 }
3270
3271 /*
3272 ** Decide whether to set new config value if somethig valid has
3273 ** been received.
3274 */
3275 if (IsLinkSpeedDefined) {
3276 pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
3277 }
3278
3279 /*
3280 ** b) Any Autonegotiation and DuplexCapabilities set?
3281 ** Please note that both belong together...
3282 */
3283 AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
3284 AutoSet = SK_FALSE;
3285 if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3286 AutoNeg_A[pAC->Index] != NULL) {
3287 AutoSet = SK_TRUE;
3288 if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
3289 AutoSet = SK_FALSE;
3290 } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
3291 AutoNeg = AN_ON;
3292 } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
3293 AutoNeg = AN_OFF;
3294 } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
3295 AutoNeg = AN_SENS;
3296 } else {
3297 printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
3298 AutoNeg_A[pAC->Index]);
3299 }
3300 }
3301
3302 DuplexCap = DC_BOTH;
3303 DupSet = SK_FALSE;
3304 if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3305 DupCap_A[pAC->Index] != NULL) {
3306 DupSet = SK_TRUE;
3307 if (strcmp(DupCap_A[pAC->Index],"")==0) {
3308 DupSet = SK_FALSE;
3309 } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
3310 DuplexCap = DC_BOTH;
3311 } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
3312 DuplexCap = DC_FULL;
3313 } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
3314 DuplexCap = DC_HALF;
3315 } else {
3316 printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
3317 DupCap_A[pAC->Index]);
3318 }
3319 }
3320
3321 /*
3322 ** Check for illegal combinations
3323 */
3324 if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3325 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3326 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3327 (pAC->ChipsetType)) {
3328 printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3329 " Using Full Duplex.\n");
3330 DuplexCap = DC_FULL;
3331 }
3332
3333 if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
3334 printk("sk98lin, Port A: DuplexCapabilities"
3335 " ignored using Sense mode\n");
3336 }
3337
3338 if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3339 printk("sk98lin: Port A: Illegal combination"
3340 " of values AutoNeg. and DuplexCap.\n Using "
3341 "Full Duplex\n");
3342 DuplexCap = DC_FULL;
3343 }
3344
3345 if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3346 DuplexCap = DC_FULL;
3347 }
3348
3349 if (!AutoSet && DupSet) {
3350 printk("sk98lin: Port A: Duplex setting not"
3351 " possible in\n default AutoNegotiation mode"
3352 " (Sense).\n Using AutoNegotiation On\n");
3353 AutoNeg = AN_ON;
3354 }
3355
3356 /*
3357 ** set the desired mode
3358 */
3359 if (AutoSet || DupSet) {
3360 pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3361 }
3362
3363 /*
3364 ** c) Any Flowcontrol-parameter set?
3365 */
3366 if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3367 FlowCtrl_A[pAC->Index] != NULL) {
3368 if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
3369 IsFlowCtrlDefined = SK_FALSE;
3370 } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
3371 FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3372 } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
3373 FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3374 } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
3375 FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3376 } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
3377 FlowCtrl = SK_FLOW_MODE_NONE;
3378 } else {
3379 printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
3380 FlowCtrl_A[pAC->Index]);
3381 IsFlowCtrlDefined = SK_FALSE;
3382 }
3383 } else {
3384 IsFlowCtrlDefined = SK_FALSE;
3385 }
3386
3387 if (IsFlowCtrlDefined) {
3388 if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3389 printk("sk98lin: Port A: FlowControl"
3390 " impossible without AutoNegotiation,"
3391 " disabled\n");
3392 FlowCtrl = SK_FLOW_MODE_NONE;
3393 }
3394 pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
3395 }
3396
3397 /*
3398 ** d) What is with the RoleParameter?
3399 */
3400 if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3401 Role_A[pAC->Index] != NULL) {
3402 if (strcmp(Role_A[pAC->Index],"")==0) {
3403 IsRoleDefined = SK_FALSE;
3404 } else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
3405 MSMode = SK_MS_MODE_AUTO;
3406 } else if (strcmp(Role_A[pAC->Index],"Master")==0) {
3407 MSMode = SK_MS_MODE_MASTER;
3408 } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
3409 MSMode = SK_MS_MODE_SLAVE;
3410 } else {
3411 printk("sk98lin: Illegal value \"%s\" for Role_A\n",
3412 Role_A[pAC->Index]);
3413 IsRoleDefined = SK_FALSE;
3414 }
3415 } else {
3416 IsRoleDefined = SK_FALSE;
3417 }
3418
3419 if (IsRoleDefined == SK_TRUE) {
3420 pAC->GIni.GP[0].PMSMode = MSMode;
3421 }
3422
3423
3424
3425 /*
3426 ** Parse any parameter settings for port B:
3427 ** a) any LinkSpeed stated?
3428 */
3429 IsConTypeDefined = SK_TRUE;
3430 IsLinkSpeedDefined = SK_TRUE;
3431 IsFlowCtrlDefined = SK_TRUE;
3432 IsModeDefined = SK_TRUE;
3433
3434 if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3435 Speed_B[pAC->Index] != NULL) {
3436 if (strcmp(Speed_B[pAC->Index],"")==0) {
3437 IsLinkSpeedDefined = SK_FALSE;
3438 } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
3439 LinkSpeed = SK_LSPEED_AUTO;
3440 } else if (strcmp(Speed_B[pAC->Index],"10")==0) {
3441 LinkSpeed = SK_LSPEED_10MBPS;
3442 } else if (strcmp(Speed_B[pAC->Index],"100")==0) {
3443 LinkSpeed = SK_LSPEED_100MBPS;
3444 } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
3445 LinkSpeed = SK_LSPEED_1000MBPS;
3446 } else {
3447 printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
3448 Speed_B[pAC->Index]);
3449 IsLinkSpeedDefined = SK_FALSE;
3450 }
3451 } else {
3452 IsLinkSpeedDefined = SK_FALSE;
3453 }
3454
3455 /*
3456 ** Check speed parameter:
3457 ** Only copper type adapter and GE V2 cards
3458 */
3459 if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3460 ((LinkSpeed != SK_LSPEED_AUTO) &&
3461 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3462 printk("sk98lin: Illegal value for Speed_B. "
3463 "Not a copper card or GE V2 card\n Using "
3464 "speed 1000\n");
3465 LinkSpeed = SK_LSPEED_1000MBPS;
3466 }
3467
3468 /*
3469 ** Decide whether to set new config value if somethig valid has
3470 ** been received.
3471 */
3472 if (IsLinkSpeedDefined) {
3473 pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
3474 }
3475
3476 /*
3477 ** b) Any Autonegotiation and DuplexCapabilities set?
3478 ** Please note that both belong together...
3479 */
3480 AutoNeg = AN_SENS; /* default: do auto Sense */
3481 AutoSet = SK_FALSE;
3482 if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3483 AutoNeg_B[pAC->Index] != NULL) {
3484 AutoSet = SK_TRUE;
3485 if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
3486 AutoSet = SK_FALSE;
3487 } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
3488 AutoNeg = AN_ON;
3489 } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
3490 AutoNeg = AN_OFF;
3491 } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
3492 AutoNeg = AN_SENS;
3493 } else {
3494 printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
3495 AutoNeg_B[pAC->Index]);
3496 }
3497 }
3498
3499 DuplexCap = DC_BOTH;
3500 DupSet = SK_FALSE;
3501 if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3502 DupCap_B[pAC->Index] != NULL) {
3503 DupSet = SK_TRUE;
3504 if (strcmp(DupCap_B[pAC->Index],"")==0) {
3505 DupSet = SK_FALSE;
3506 } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
3507 DuplexCap = DC_BOTH;
3508 } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
3509 DuplexCap = DC_FULL;
3510 } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
3511 DuplexCap = DC_HALF;
3512 } else {
3513 printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
3514 DupCap_B[pAC->Index]);
3515 }
3516 }
3517
3518
3519 /*
3520 ** Check for illegal combinations
3521 */
3522 if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3523 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3524 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3525 (pAC->ChipsetType)) {
3526 printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3527 " Using Full Duplex.\n");
3528 DuplexCap = DC_FULL;
3529 }
3530
3531 if (AutoSet && AutoNeg==AN_SENS && DupSet) {
3532 printk("sk98lin, Port B: DuplexCapabilities"
3533 " ignored using Sense mode\n");
3534 }
3535
3536 if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3537 printk("sk98lin: Port B: Illegal combination"
3538 " of values AutoNeg. and DuplexCap.\n Using "
3539 "Full Duplex\n");
3540 DuplexCap = DC_FULL;
3541 }
3542
3543 if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3544 DuplexCap = DC_FULL;
3545 }
3546
3547 if (!AutoSet && DupSet) {
3548 printk("sk98lin: Port B: Duplex setting not"
3549 " possible in\n default AutoNegotiation mode"
3550 " (Sense).\n Using AutoNegotiation On\n");
3551 AutoNeg = AN_ON;
3552 }
3553
3554 /*
3555 ** set the desired mode
3556 */
3557 if (AutoSet || DupSet) {
3558 pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3559 }
3560
3561 /*
3562 ** c) Any FlowCtrl parameter set?
3563 */
3564 if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3565 FlowCtrl_B[pAC->Index] != NULL) {
3566 if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
3567 IsFlowCtrlDefined = SK_FALSE;
3568 } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
3569 FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3570 } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
3571 FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3572 } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
3573 FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3574 } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
3575 FlowCtrl = SK_FLOW_MODE_NONE;
3576 } else {
3577 printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
3578 FlowCtrl_B[pAC->Index]);
3579 IsFlowCtrlDefined = SK_FALSE;
3580 }
3581 } else {
3582 IsFlowCtrlDefined = SK_FALSE;
3583 }
3584
3585 if (IsFlowCtrlDefined) {
3586 if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3587 printk("sk98lin: Port B: FlowControl"
3588 " impossible without AutoNegotiation,"
3589 " disabled\n");
3590 FlowCtrl = SK_FLOW_MODE_NONE;
3591 }
3592 pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
3593 }
3594
3595 /*
3596 ** d) What is the RoleParameter?
3597 */
3598 if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3599 Role_B[pAC->Index] != NULL) {
3600 if (strcmp(Role_B[pAC->Index],"")==0) {
3601 IsRoleDefined = SK_FALSE;
3602 } else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
3603 MSMode = SK_MS_MODE_AUTO;
3604 } else if (strcmp(Role_B[pAC->Index],"Master")==0) {
3605 MSMode = SK_MS_MODE_MASTER;
3606 } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
3607 MSMode = SK_MS_MODE_SLAVE;
3608 } else {
3609 printk("sk98lin: Illegal value \"%s\" for Role_B\n",
3610 Role_B[pAC->Index]);
3611 IsRoleDefined = SK_FALSE;
3612 }
3613 } else {
3614 IsRoleDefined = SK_FALSE;
3615 }
3616
3617 if (IsRoleDefined) {
3618 pAC->GIni.GP[1].PMSMode = MSMode;
3619 }
3620
3621 /*
3622 ** Evaluate settings for both ports
3623 */
3624 pAC->ActivePort = 0;
3625 if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3626 PrefPort[pAC->Index] != NULL) {
3627 if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
3628 pAC->ActivePort = 0;
3629 pAC->Rlmt.Net[0].Preference = -1; /* auto */
3630 pAC->Rlmt.Net[0].PrefPort = 0;
3631 } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
3632 /*
3633 ** do not set ActivePort here, thus a port
3634 ** switch is issued after net up.
3635 */
3636 Port = 0;
3637 pAC->Rlmt.Net[0].Preference = Port;
3638 pAC->Rlmt.Net[0].PrefPort = Port;
3639 } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
3640 /*
3641 ** do not set ActivePort here, thus a port
3642 ** switch is issued after net up.
3643 */
3644 if (pAC->GIni.GIMacsFound == 1) {
3645 printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
3646 " Port B not available on single port adapters.\n");
3647
3648 pAC->ActivePort = 0;
3649 pAC->Rlmt.Net[0].Preference = -1; /* auto */
3650 pAC->Rlmt.Net[0].PrefPort = 0;
3651 } else {
3652 Port = 1;
3653 pAC->Rlmt.Net[0].Preference = Port;
3654 pAC->Rlmt.Net[0].PrefPort = Port;
3655 }
3656 } else {
3657 printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
3658 PrefPort[pAC->Index]);
3659 }
3660 }
3661
3662 pAC->RlmtNets = 1;
3663
3664 if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3665 RlmtMode[pAC->Index] != NULL) {
3666 if (strcmp(RlmtMode[pAC->Index], "") == 0) {
3667 pAC->RlmtMode = 0;
3668 } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
3669 pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3670 } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
3671 pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3672 SK_RLMT_CHECK_LOC_LINK;
3673 } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
3674 pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3675 SK_RLMT_CHECK_LOC_LINK |
3676 SK_RLMT_CHECK_SEG;
3677 } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
3678 (pAC->GIni.GIMacsFound == 2)) {
3679 pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3680 pAC->RlmtNets = 2;
3681 } else {
3682 printk("sk98lin: Illegal value \"%s\" for"
3683 " RlmtMode, using default\n",
3684 RlmtMode[pAC->Index]);
3685 pAC->RlmtMode = 0;
3686 }
3687 } else {
3688 pAC->RlmtMode = 0;
3689 }
3690
3691 /*
3692 ** Check the interrupt moderation parameters
3693 */
3694 if (Moderation[pAC->Index] != NULL) {
3695 if (strcmp(Moderation[pAC->Index], "") == 0) {
3696 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3697 } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
3698 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
3699 } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
3700 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
3701 } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
3702 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3703 } else {
3704 printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
3705 " Disable interrupt moderation.\n",
3706 Moderation[pAC->Index]);
3707 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3708 }
3709 } else {
3710 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3711 }
3712
3713 if (Stats[pAC->Index] != NULL) {
3714 if (strcmp(Stats[pAC->Index], "Yes") == 0) {
3715 pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
3716 } else {
3717 pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3718 }
3719 } else {
3720 pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3721 }
3722
3723 if (ModerationMask[pAC->Index] != NULL) {
3724 if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
3725 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3726 } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
3727 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
3728 } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
3729 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
3730 } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
3731 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3732 } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
3733 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3734 } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
3735 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3736 } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
3737 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3738 } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
3739 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3740 } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
3741 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3742 } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
3743 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3744 } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
3745 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3746 } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
3747 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3748 } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
3749 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3750 } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
3751 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3752 } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
3753 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3754 } else { /* some rubbish */
3755 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3756 }
3757 } else { /* operator has stated nothing */
3758 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3759 }
3760
3761 if (AutoSizing[pAC->Index] != NULL) {
3762 if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
3763 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3764 } else {
3765 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3766 }
3767 } else { /* operator has stated nothing */
3768 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3769 }
3770
3771 if (IntsPerSec[pAC->Index] != 0) {
3772 if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) ||
3773 (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
3774 printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
3775 " Using default value of %i.\n",
3776 IntsPerSec[pAC->Index],
3777 C_INT_MOD_IPS_LOWER_RANGE,
3778 C_INT_MOD_IPS_UPPER_RANGE,
3779 C_INTS_PER_SEC_DEFAULT);
3780 pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3781 } else {
3782 pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
3783 }
3784 } else {
3785 pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3786 }
3787
3788 /*
3789 ** Evaluate upper and lower moderation threshold
3790 */
3791 pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
3792 pAC->DynIrqModInfo.MaxModIntsPerSec +
3793 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3794
3795 pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
3796 pAC->DynIrqModInfo.MaxModIntsPerSec -
3797 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3798
3799 pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */
3800
3801
3802} /* GetConfiguration */
3803
3804
3805/*****************************************************************************
3806 *
3807 * ProductStr - return a adapter identification string from vpd
3808 *
3809 * Description:
3810 * This function reads the product name string from the vpd area
3811 * and puts it the field pAC->DeviceString.
3812 *
3813 * Returns: N/A
3814 */
3815static inline int ProductStr(
3816 SK_AC *pAC, /* pointer to adapter context */
3817 char *DeviceStr, /* result string */
3818 int StrLen /* length of the string */
3819)
3820{
3821char Keyword[] = VPD_NAME; /* vpd productname identifier */
3822int ReturnCode; /* return code from vpd_read */
3823unsigned long Flags;
3824
3825 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3826 ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
3827 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3828
3829 return ReturnCode;
3830} /* ProductStr */
3831
3832/*****************************************************************************
3833 *
3834 * StartDrvCleanupTimer - Start timer to check for descriptors which
3835 * might be placed in descriptor ring, but
3836 * havent been handled up to now
3837 *
3838 * Description:
3839 * This function requests a HW-timer fo the Yukon card. The actions to
3840 * perform when this timer expires, are located in the SkDrvEvent().
3841 *
3842 * Returns: N/A
3843 */
3844static void
3845StartDrvCleanupTimer(SK_AC *pAC) {
3846 SK_EVPARA EventParam; /* Event struct for timer event */
3847
3848 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
3849 EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
3850 SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
3851 SK_DRV_RX_CLEANUP_TIMER_LENGTH,
3852 SKGE_DRV, SK_DRV_TIMER, EventParam);
3853}
3854
3855/*****************************************************************************
3856 *
3857 * StopDrvCleanupTimer - Stop timer to check for descriptors
3858 *
3859 * Description:
3860 * This function requests a HW-timer fo the Yukon card. The actions to
3861 * perform when this timer expires, are located in the SkDrvEvent().
3862 *
3863 * Returns: N/A
3864 */
3865static void
3866StopDrvCleanupTimer(SK_AC *pAC) {
3867 SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
3868 SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
3869}
3870
3871/****************************************************************************/
3872/* functions for common modules *********************************************/
3873/****************************************************************************/
3874
3875
3876/*****************************************************************************
3877 *
3878 * SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
3879 *
3880 * Description:
3881 * This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
3882 * is embedded into a socket buff data area.
3883 *
3884 * Context:
3885 * runtime
3886 *
3887 * Returns:
3888 * NULL or pointer to Mbuf.
3889 */
3890SK_MBUF *SkDrvAllocRlmtMbuf(
3891SK_AC *pAC, /* pointer to adapter context */
3892SK_IOC IoC, /* the IO-context */
3893unsigned BufferSize) /* size of the requested buffer */
3894{
3895SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */
3896struct sk_buff *pMsgBlock; /* pointer to a new message block */
3897
3898 pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
3899 if (pMsgBlock == NULL) {
3900 return (NULL);
3901 }
3902 pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
3903 skb_reserve(pMsgBlock, sizeof(SK_MBUF));
3904 pRlmtMbuf->pNext = NULL;
3905 pRlmtMbuf->pOs = pMsgBlock;
3906 pRlmtMbuf->pData = pMsgBlock->data; /* Data buffer. */
3907 pRlmtMbuf->Size = BufferSize; /* Data buffer size. */
3908 pRlmtMbuf->Length = 0; /* Length of packet (<= Size). */
3909 return (pRlmtMbuf);
3910
3911} /* SkDrvAllocRlmtMbuf */
3912
3913
3914/*****************************************************************************
3915 *
3916 * SkDrvFreeRlmtMbuf - free an RLMT mbuf
3917 *
3918 * Description:
3919 * This routine frees one or more RLMT mbuf(s).
3920 *
3921 * Context:
3922 * runtime
3923 *
3924 * Returns:
3925 * Nothing
3926 */
3927void SkDrvFreeRlmtMbuf(
3928SK_AC *pAC, /* pointer to adapter context */
3929SK_IOC IoC, /* the IO-context */
3930SK_MBUF *pMbuf) /* size of the requested buffer */
3931{
3932SK_MBUF *pFreeMbuf;
3933SK_MBUF *pNextMbuf;
3934
3935 pFreeMbuf = pMbuf;
3936 do {
3937 pNextMbuf = pFreeMbuf->pNext;
3938 DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
3939 pFreeMbuf = pNextMbuf;
3940 } while ( pFreeMbuf != NULL );
3941} /* SkDrvFreeRlmtMbuf */
3942
3943
3944/*****************************************************************************
3945 *
3946 * SkOsGetTime - provide a time value
3947 *
3948 * Description:
3949 * This routine provides a time value. The unit is 1/HZ (defined by Linux).
3950 * It is not used for absolute time, but only for time differences.
3951 *
3952 *
3953 * Returns:
3954 * Time value
3955 */
3956SK_U64 SkOsGetTime(SK_AC *pAC)
3957{
3958 SK_U64 PrivateJiffies;
3959 SkOsGetTimeCurrent(pAC, &PrivateJiffies);
3960 return PrivateJiffies;
3961} /* SkOsGetTime */
3962
3963
3964/*****************************************************************************
3965 *
3966 * SkPciReadCfgDWord - read a 32 bit value from pci config space
3967 *
3968 * Description:
3969 * This routine reads a 32 bit value from the pci configuration
3970 * space.
3971 *
3972 * Returns:
3973 * 0 - indicate everything worked ok.
3974 * != 0 - error indication
3975 */
3976int SkPciReadCfgDWord(
3977SK_AC *pAC, /* Adapter Control structure pointer */
3978int PciAddr, /* PCI register address */
3979SK_U32 *pVal) /* pointer to store the read value */
3980{
3981 pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
3982 return(0);
3983} /* SkPciReadCfgDWord */
3984
3985
3986/*****************************************************************************
3987 *
3988 * SkPciReadCfgWord - read a 16 bit value from pci config space
3989 *
3990 * Description:
3991 * This routine reads a 16 bit value from the pci configuration
3992 * space.
3993 *
3994 * Returns:
3995 * 0 - indicate everything worked ok.
3996 * != 0 - error indication
3997 */
3998int SkPciReadCfgWord(
3999SK_AC *pAC, /* Adapter Control structure pointer */
4000int PciAddr, /* PCI register address */
4001SK_U16 *pVal) /* pointer to store the read value */
4002{
4003 pci_read_config_word(pAC->PciDev, PciAddr, pVal);
4004 return(0);
4005} /* SkPciReadCfgWord */
4006
4007
4008/*****************************************************************************
4009 *
4010 * SkPciReadCfgByte - read a 8 bit value from pci config space
4011 *
4012 * Description:
4013 * This routine reads a 8 bit value from the pci configuration
4014 * space.
4015 *
4016 * Returns:
4017 * 0 - indicate everything worked ok.
4018 * != 0 - error indication
4019 */
4020int SkPciReadCfgByte(
4021SK_AC *pAC, /* Adapter Control structure pointer */
4022int PciAddr, /* PCI register address */
4023SK_U8 *pVal) /* pointer to store the read value */
4024{
4025 pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
4026 return(0);
4027} /* SkPciReadCfgByte */
4028
4029
4030/*****************************************************************************
4031 *
4032 * SkPciWriteCfgWord - write a 16 bit value to pci config space
4033 *
4034 * Description:
4035 * This routine writes a 16 bit value to the pci configuration
4036 * space. The flag PciConfigUp indicates whether the config space
4037 * is accesible or must be set up first.
4038 *
4039 * Returns:
4040 * 0 - indicate everything worked ok.
4041 * != 0 - error indication
4042 */
4043int SkPciWriteCfgWord(
4044SK_AC *pAC, /* Adapter Control structure pointer */
4045int PciAddr, /* PCI register address */
4046SK_U16 Val) /* pointer to store the read value */
4047{
4048 pci_write_config_word(pAC->PciDev, PciAddr, Val);
4049 return(0);
4050} /* SkPciWriteCfgWord */
4051
4052
4053/*****************************************************************************
4054 *
4055 * SkPciWriteCfgWord - write a 8 bit value to pci config space
4056 *
4057 * Description:
4058 * This routine writes a 8 bit value to the pci configuration
4059 * space. The flag PciConfigUp indicates whether the config space
4060 * is accesible or must be set up first.
4061 *
4062 * Returns:
4063 * 0 - indicate everything worked ok.
4064 * != 0 - error indication
4065 */
4066int SkPciWriteCfgByte(
4067SK_AC *pAC, /* Adapter Control structure pointer */
4068int PciAddr, /* PCI register address */
4069SK_U8 Val) /* pointer to store the read value */
4070{
4071 pci_write_config_byte(pAC->PciDev, PciAddr, Val);
4072 return(0);
4073} /* SkPciWriteCfgByte */
4074
4075
4076/*****************************************************************************
4077 *
4078 * SkDrvEvent - handle driver events
4079 *
4080 * Description:
4081 * This function handles events from all modules directed to the driver
4082 *
4083 * Context:
4084 * Is called under protection of slow path lock.
4085 *
4086 * Returns:
4087 * 0 if everything ok
4088 * < 0 on error
4089 *
4090 */
4091int SkDrvEvent(
4092SK_AC *pAC, /* pointer to adapter context */
4093SK_IOC IoC, /* io-context */
4094SK_U32 Event, /* event-id */
4095SK_EVPARA Param) /* event-parameter */
4096{
4097SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */
4098struct sk_buff *pMsg; /* pointer to a message block */
4099int FromPort; /* the port from which we switch away */
4100int ToPort; /* the port we switch to */
4101SK_EVPARA NewPara; /* parameter for further events */
4102int Stat;
4103unsigned long Flags;
4104SK_BOOL DualNet;
4105
4106 switch (Event) {
4107 case SK_DRV_ADAP_FAIL:
4108 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4109 ("ADAPTER FAIL EVENT\n"));
4110 printk("%s: Adapter failed.\n", pAC->dev[0]->name);
4111 /* disable interrupts */
4112 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
4113 /* cgoos */
4114 break;
4115 case SK_DRV_PORT_FAIL:
4116 FromPort = Param.Para32[0];
4117 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4118 ("PORT FAIL EVENT, Port: %d\n", FromPort));
4119 if (FromPort == 0) {
4120 printk("%s: Port A failed.\n", pAC->dev[0]->name);
4121 } else {
4122 printk("%s: Port B failed.\n", pAC->dev[1]->name);
4123 }
4124 /* cgoos */
4125 break;
4126 case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */
4127 /* action list 4 */
4128 FromPort = Param.Para32[0];
4129 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4130 ("PORT RESET EVENT, Port: %d ", FromPort));
4131 NewPara.Para64 = FromPort;
4132 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4133 spin_lock_irqsave(
4134 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4135 Flags);
4136
4137 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
4138 netif_carrier_off(pAC->dev[Param.Para32[0]]);
4139 spin_unlock_irqrestore(
4140 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4141 Flags);
4142
4143 /* clear rx ring from received frames */
4144 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
4145
4146 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4147 spin_lock_irqsave(
4148 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4149 Flags);
4150
4151 /* tschilling: Handling of return value inserted. */
4152 if (SkGeInitPort(pAC, IoC, FromPort)) {
4153 if (FromPort == 0) {
4154 printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
4155 } else {
4156 printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
4157 }
4158 }
4159 SkAddrMcUpdate(pAC,IoC, FromPort);
4160 PortReInitBmu(pAC, FromPort);
4161 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4162 ClearAndStartRx(pAC, FromPort);
4163 spin_unlock_irqrestore(
4164 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4165 Flags);
4166 break;
4167 case SK_DRV_NET_UP: /* SK_U32 PortIdx */
4168 { struct net_device *dev = pAC->dev[Param.Para32[0]];
4169 /* action list 5 */
4170 FromPort = Param.Para32[0];
4171 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4172 ("NET UP EVENT, Port: %d ", Param.Para32[0]));
4173 /* Mac update */
4174 SkAddrMcUpdate(pAC,IoC, FromPort);
4175
4176 if (DoPrintInterfaceChange) {
4177 printk("%s: network connection up using"
4178 " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
4179
4180 /* tschilling: Values changed according to LinkSpeedUsed. */
4181 Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
4182 if (Stat == SK_LSPEED_STAT_10MBPS) {
4183 printk(" speed: 10\n");
4184 } else if (Stat == SK_LSPEED_STAT_100MBPS) {
4185 printk(" speed: 100\n");
4186 } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
4187 printk(" speed: 1000\n");
4188 } else {
4189 printk(" speed: unknown\n");
4190 }
4191
4192
4193 Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
4194 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4195 Stat == SK_LMODE_STAT_AUTOFULL) {
4196 printk(" autonegotiation: yes\n");
4197 }
4198 else {
4199 printk(" autonegotiation: no\n");
4200 }
4201 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4202 Stat == SK_LMODE_STAT_HALF) {
4203 printk(" duplex mode: half\n");
4204 }
4205 else {
4206 printk(" duplex mode: full\n");
4207 }
4208 Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
4209 if (Stat == SK_FLOW_STAT_REM_SEND ) {
4210 printk(" flowctrl: remote send\n");
4211 }
4212 else if (Stat == SK_FLOW_STAT_LOC_SEND ){
4213 printk(" flowctrl: local send\n");
4214 }
4215 else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
4216 printk(" flowctrl: symmetric\n");
4217 }
4218 else {
4219 printk(" flowctrl: none\n");
4220 }
4221
4222 /* tschilling: Check against CopperType now. */
4223 if ((pAC->GIni.GICopperType == SK_TRUE) &&
4224 (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
4225 SK_LSPEED_STAT_1000MBPS)) {
4226 Stat = pAC->GIni.GP[FromPort].PMSStatus;
4227 if (Stat == SK_MS_STAT_MASTER ) {
4228 printk(" role: master\n");
4229 }
4230 else if (Stat == SK_MS_STAT_SLAVE ) {
4231 printk(" role: slave\n");
4232 }
4233 else {
4234 printk(" role: ???\n");
4235 }
4236 }
4237
4238 /*
4239 Display dim (dynamic interrupt moderation)
4240 informations
4241 */
4242 if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
4243 printk(" irq moderation: static (%d ints/sec)\n",
4244 pAC->DynIrqModInfo.MaxModIntsPerSec);
4245 else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
4246 printk(" irq moderation: dynamic (%d ints/sec)\n",
4247 pAC->DynIrqModInfo.MaxModIntsPerSec);
4248 else
4249 printk(" irq moderation: disabled\n");
4250
4251
4252 printk(" scatter-gather: %s\n",
4253 (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
4254 printk(" tx-checksum: %s\n",
4255 (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
4256 printk(" rx-checksum: %s\n",
4257 pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
4258
4259 } else {
4260 DoPrintInterfaceChange = SK_TRUE;
4261 }
4262
4263 if ((Param.Para32[0] != pAC->ActivePort) &&
4264 (pAC->RlmtNets == 1)) {
4265 NewPara.Para32[0] = pAC->ActivePort;
4266 NewPara.Para32[1] = Param.Para32[0];
4267 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
4268 NewPara);
4269 }
4270
4271 /* Inform the world that link protocol is up. */
4272 netif_carrier_on(dev);
4273 break;
4274 }
4275 case SK_DRV_NET_DOWN: /* SK_U32 Reason */
4276 /* action list 7 */
4277 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4278 ("NET DOWN EVENT "));
4279 if (DoPrintInterfaceChange) {
4280 printk("%s: network connection down\n",
4281 pAC->dev[Param.Para32[1]]->name);
4282 } else {
4283 DoPrintInterfaceChange = SK_TRUE;
4284 }
4285 netif_carrier_off(pAC->dev[Param.Para32[1]]);
4286 break;
4287 case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4288 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4289 ("PORT SWITCH HARD "));
4290 case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4291 /* action list 6 */
4292 printk("%s: switching to port %c\n", pAC->dev[0]->name,
4293 'A'+Param.Para32[1]);
4294 case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4295 FromPort = Param.Para32[0];
4296 ToPort = Param.Para32[1];
4297 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4298 ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ",
4299 FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
4300 NewPara.Para64 = FromPort;
4301 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4302 NewPara.Para64 = ToPort;
4303 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4304 spin_lock_irqsave(
4305 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4306 Flags);
4307 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4308 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
4309 SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
4310 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4311 spin_unlock_irqrestore(
4312 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4313 Flags);
4314
4315 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
4316 ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
4317
4318 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4319 ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
4320 spin_lock_irqsave(
4321 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4322 Flags);
4323 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4324 pAC->ActivePort = ToPort;
4325#if 0
4326 SetQueueSizes(pAC);
4327#else
4328 /* tschilling: New common function with minimum size check. */
4329 DualNet = SK_FALSE;
4330 if (pAC->RlmtNets == 2) {
4331 DualNet = SK_TRUE;
4332 }
4333
4334 if (SkGeInitAssignRamToQueues(
4335 pAC,
4336 pAC->ActivePort,
4337 DualNet)) {
4338 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4339 spin_unlock_irqrestore(
4340 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4341 Flags);
4342 printk("SkGeInitAssignRamToQueues failed.\n");
4343 break;
4344 }
4345#endif
4346 /* tschilling: Handling of return values inserted. */
4347 if (SkGeInitPort(pAC, IoC, FromPort) ||
4348 SkGeInitPort(pAC, IoC, ToPort)) {
4349 printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
4350 }
4351 if (Event == SK_DRV_SWITCH_SOFT) {
4352 SkMacRxTxEnable(pAC, IoC, FromPort);
4353 }
4354 SkMacRxTxEnable(pAC, IoC, ToPort);
4355 SkAddrSwap(pAC, IoC, FromPort, ToPort);
4356 SkAddrMcUpdate(pAC, IoC, FromPort);
4357 SkAddrMcUpdate(pAC, IoC, ToPort);
4358 PortReInitBmu(pAC, FromPort);
4359 PortReInitBmu(pAC, ToPort);
4360 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4361 SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
4362 ClearAndStartRx(pAC, FromPort);
4363 ClearAndStartRx(pAC, ToPort);
4364 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4365 spin_unlock_irqrestore(
4366 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4367 Flags);
4368 break;
4369 case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */
4370 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4371 ("RLS "));
4372 pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
4373 pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
4374 skb_put(pMsg, pRlmtMbuf->Length);
4375 if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
4376 pMsg) < 0)
4377
4378 DEV_KFREE_SKB_ANY(pMsg);
4379 break;
4380 case SK_DRV_TIMER:
4381 if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
4382 /*
4383 ** expiration of the moderation timer implies that
4384 ** dynamic moderation is to be applied
4385 */
4386 SkDimStartModerationTimer(pAC);
4387 SkDimModerate(pAC);
4388 if (pAC->DynIrqModInfo.DisplayStats) {
4389 SkDimDisplayModerationSettings(pAC);
4390 }
4391 } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
4392 /*
4393 ** check if we need to check for descriptors which
4394 ** haven't been handled the last millisecs
4395 */
4396 StartDrvCleanupTimer(pAC);
4397 if (pAC->GIni.GIMacsFound == 2) {
4398 ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
4399 }
4400 ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
4401 } else {
4402 printk("Expiration of unknown timer\n");
4403 }
4404 break;
4405 default:
4406 break;
4407 }
4408 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4409 ("END EVENT "));
4410
4411 return (0);
4412} /* SkDrvEvent */
4413
4414
4415/*****************************************************************************
4416 *
4417 * SkErrorLog - log errors
4418 *
4419 * Description:
4420 * This function logs errors to the system buffer and to the console
4421 *
4422 * Returns:
4423 * 0 if everything ok
4424 * < 0 on error
4425 *
4426 */
4427void SkErrorLog(
4428SK_AC *pAC,
4429int ErrClass,
4430int ErrNum,
4431char *pErrorMsg)
4432{
4433char ClassStr[80];
4434
4435 switch (ErrClass) {
4436 case SK_ERRCL_OTHER:
4437 strcpy(ClassStr, "Other error");
4438 break;
4439 case SK_ERRCL_CONFIG:
4440 strcpy(ClassStr, "Configuration error");
4441 break;
4442 case SK_ERRCL_INIT:
4443 strcpy(ClassStr, "Initialization error");
4444 break;
4445 case SK_ERRCL_NORES:
4446 strcpy(ClassStr, "Out of resources error");
4447 break;
4448 case SK_ERRCL_SW:
4449 strcpy(ClassStr, "internal Software error");
4450 break;
4451 case SK_ERRCL_HW:
4452 strcpy(ClassStr, "Hardware failure");
4453 break;
4454 case SK_ERRCL_COMM:
4455 strcpy(ClassStr, "Communication error");
4456 break;
4457 }
4458 printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n"
4459 " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name,
4460 ClassStr, ErrNum, pErrorMsg);
4461
4462} /* SkErrorLog */
4463
4464#ifdef SK_DIAG_SUPPORT
4465
4466/*****************************************************************************
4467 *
4468 * SkDrvEnterDiagMode - handles DIAG attach request
4469 *
4470 * Description:
4471 * Notify the kernel to NOT access the card any longer due to DIAG
4472 * Deinitialize the Card
4473 *
4474 * Returns:
4475 * int
4476 */
4477int SkDrvEnterDiagMode(
4478SK_AC *pAc) /* pointer to adapter context */
4479{
4480 DEV_NET *pNet = netdev_priv(pAc->dev[0]);
4481 SK_AC *pAC = pNet->pAC;
4482
4483 SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct),
4484 sizeof(SK_PNMI_STRUCT_DATA));
4485
4486 pAC->DiagModeActive = DIAG_ACTIVE;
4487 if (pAC->BoardLevel > SK_INIT_DATA) {
4488 if (netif_running(pAC->dev[0])) {
4489 pAC->WasIfUp[0] = SK_TRUE;
4490 pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4491 DoPrintInterfaceChange = SK_FALSE;
4492 SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */
4493 } else {
4494 pAC->WasIfUp[0] = SK_FALSE;
4495 }
4496 if (pNet != netdev_priv(pAC->dev[1])) {
4497 pNet = netdev_priv(pAC->dev[1]);
4498 if (netif_running(pAC->dev[1])) {
4499 pAC->WasIfUp[1] = SK_TRUE;
4500 pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4501 DoPrintInterfaceChange = SK_FALSE;
4502 SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */
4503 } else {
4504 pAC->WasIfUp[1] = SK_FALSE;
4505 }
4506 }
4507 pAC->BoardLevel = SK_INIT_DATA;
4508 }
4509 return(0);
4510}
4511
4512/*****************************************************************************
4513 *
4514 * SkDrvLeaveDiagMode - handles DIAG detach request
4515 *
4516 * Description:
4517 * Notify the kernel to may access the card again after use by DIAG
4518 * Initialize the Card
4519 *
4520 * Returns:
4521 * int
4522 */
4523int SkDrvLeaveDiagMode(
4524SK_AC *pAc) /* pointer to adapter control context */
4525{
4526 SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup),
4527 sizeof(SK_PNMI_STRUCT_DATA));
4528 pAc->DiagModeActive = DIAG_NOTACTIVE;
4529 pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
4530 if (pAc->WasIfUp[0] == SK_TRUE) {
4531 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4532 DoPrintInterfaceChange = SK_FALSE;
4533 SkDrvInitAdapter(pAc, 0); /* first device */
4534 }
4535 if (pAc->WasIfUp[1] == SK_TRUE) {
4536 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4537 DoPrintInterfaceChange = SK_FALSE;
4538 SkDrvInitAdapter(pAc, 1); /* second device */
4539 }
4540 return(0);
4541}
4542
4543/*****************************************************************************
4544 *
4545 * ParseDeviceNbrFromSlotName - Evaluate PCI device number
4546 *
4547 * Description:
4548 * This function parses the PCI slot name information string and will
4549 * retrieve the devcie number out of it. The slot_name maintianed by
4550 * linux is in the form of '02:0a.0', whereas the first two characters
4551 * represent the bus number in hex (in the sample above this is
4552 * pci bus 0x02) and the next two characters the device number (0x0a).
4553 *
4554 * Returns:
4555 * SK_U32: The device number from the PCI slot name
4556 */
4557
4558static SK_U32 ParseDeviceNbrFromSlotName(
4559const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */
4560{
4561 char *CurrCharPos = (char *) SlotName;
4562 int FirstNibble = -1;
4563 int SecondNibble = -1;
4564 SK_U32 Result = 0;
4565
4566 while (*CurrCharPos != '\0') {
4567 if (*CurrCharPos == ':') {
4568 while (*CurrCharPos != '.') {
4569 CurrCharPos++;
4570 if ( (*CurrCharPos >= '0') &&
4571 (*CurrCharPos <= '9')) {
4572 if (FirstNibble == -1) {
4573 /* dec. value for '0' */
4574 FirstNibble = *CurrCharPos - 48;
4575 } else {
4576 SecondNibble = *CurrCharPos - 48;
4577 }
4578 } else if ( (*CurrCharPos >= 'a') &&
4579 (*CurrCharPos <= 'f') ) {
4580 if (FirstNibble == -1) {
4581 FirstNibble = *CurrCharPos - 87;
4582 } else {
4583 SecondNibble = *CurrCharPos - 87;
4584 }
4585 } else {
4586 Result = 0;
4587 }
4588 }
4589
4590 Result = FirstNibble;
4591 Result = Result << 4; /* first nibble is higher one */
4592 Result = Result | SecondNibble;
4593 }
4594 CurrCharPos++; /* next character */
4595 }
4596 return (Result);
4597}
4598
4599/****************************************************************************
4600 *
4601 * SkDrvDeInitAdapter - deinitialize adapter (this function is only
4602 * called if Diag attaches to that card)
4603 *
4604 * Description:
4605 * Close initialized adapter.
4606 *
4607 * Returns:
4608 * 0 - on success
4609 * error code - on error
4610 */
4611static int SkDrvDeInitAdapter(
4612SK_AC *pAC, /* pointer to adapter context */
4613int devNbr) /* what device is to be handled */
4614{
4615 struct SK_NET_DEVICE *dev;
4616
4617 dev = pAC->dev[devNbr];
4618
4619 /* On Linux 2.6 the network driver does NOT mess with reference
4620 ** counts. The driver MUST be able to be unloaded at any time
4621 ** due to the possibility of hotplug.
4622 */
4623 if (SkGeClose(dev) != 0) {
4624 return (-1);
4625 }
4626 return (0);
4627
4628} /* SkDrvDeInitAdapter() */
4629
4630/****************************************************************************
4631 *
4632 * SkDrvInitAdapter - Initialize adapter (this function is only
4633 * called if Diag deattaches from that card)
4634 *
4635 * Description:
4636 * Close initialized adapter.
4637 *
4638 * Returns:
4639 * 0 - on success
4640 * error code - on error
4641 */
4642static int SkDrvInitAdapter(
4643SK_AC *pAC, /* pointer to adapter context */
4644int devNbr) /* what device is to be handled */
4645{
4646 struct SK_NET_DEVICE *dev;
4647
4648 dev = pAC->dev[devNbr];
4649
4650 if (SkGeOpen(dev) != 0) {
4651 return (-1);
4652 }
4653
4654 /*
4655 ** Use correct MTU size and indicate to kernel TX queue can be started
4656 */
4657 if (SkGeChangeMtu(dev, dev->mtu) != 0) {
4658 return (-1);
4659 }
4660 return (0);
4661
4662} /* SkDrvInitAdapter */
4663
4664#endif
4665
4666#ifdef DEBUG
4667/****************************************************************************/
4668/* "debug only" section *****************************************************/
4669/****************************************************************************/
4670
4671
4672/*****************************************************************************
4673 *
4674 * DumpMsg - print a frame
4675 *
4676 * Description:
4677 * This function prints frames to the system logfile/to the console.
4678 *
4679 * Returns: N/A
4680 *
4681 */
4682static void DumpMsg(struct sk_buff *skb, char *str)
4683{
4684 int msglen;
4685
4686 if (skb == NULL) {
4687 printk("DumpMsg(): NULL-Message\n");
4688 return;
4689 }
4690
4691 if (skb->data == NULL) {
4692 printk("DumpMsg(): Message empty\n");
4693 return;
4694 }
4695
4696 msglen = skb->len;
4697 if (msglen > 64)
4698 msglen = 64;
4699
4700 printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
4701
4702 DumpData((char *)skb->data, msglen);
4703
4704 printk("------- End of message ---------\n");
4705} /* DumpMsg */
4706
4707
4708
4709/*****************************************************************************
4710 *
4711 * DumpData - print a data area
4712 *
4713 * Description:
4714 * This function prints a area of data to the system logfile/to the
4715 * console.
4716 *
4717 * Returns: N/A
4718 *
4719 */
4720static void DumpData(char *p, int size)
4721{
4722register int i;
4723int haddr, addr;
4724char hex_buffer[180];
4725char asc_buffer[180];
4726char HEXCHAR[] = "0123456789ABCDEF";
4727
4728 addr = 0;
4729 haddr = 0;
4730 hex_buffer[0] = 0;
4731 asc_buffer[0] = 0;
4732 for (i=0; i < size; ) {
4733 if (*p >= '0' && *p <='z')
4734 asc_buffer[addr] = *p;
4735 else
4736 asc_buffer[addr] = '.';
4737 addr++;
4738 asc_buffer[addr] = 0;
4739 hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
4740 haddr++;
4741 hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
4742 haddr++;
4743 hex_buffer[haddr] = ' ';
4744 haddr++;
4745 hex_buffer[haddr] = 0;
4746 p++;
4747 i++;
4748 if (i%16 == 0) {
4749 printk("%s %s\n", hex_buffer, asc_buffer);
4750 addr = 0;
4751 haddr = 0;
4752 }
4753 }
4754} /* DumpData */
4755
4756
4757/*****************************************************************************
4758 *
4759 * DumpLong - print a data area as long values
4760 *
4761 * Description:
4762 * This function prints a area of data to the system logfile/to the
4763 * console.
4764 *
4765 * Returns: N/A
4766 *
4767 */
4768static void DumpLong(char *pc, int size)
4769{
4770register int i;
4771int haddr, addr;
4772char hex_buffer[180];
4773char asc_buffer[180];
4774char HEXCHAR[] = "0123456789ABCDEF";
4775long *p;
4776int l;
4777
4778 addr = 0;
4779 haddr = 0;
4780 hex_buffer[0] = 0;
4781 asc_buffer[0] = 0;
4782 p = (long*) pc;
4783 for (i=0; i < size; ) {
4784 l = (long) *p;
4785 hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
4786 haddr++;
4787 hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
4788 haddr++;
4789 hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
4790 haddr++;
4791 hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
4792 haddr++;
4793 hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
4794 haddr++;
4795 hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
4796 haddr++;
4797 hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
4798 haddr++;
4799 hex_buffer[haddr] = HEXCHAR[l & 0x0f];
4800 haddr++;
4801 hex_buffer[haddr] = ' ';
4802 haddr++;
4803 hex_buffer[haddr] = 0;
4804 p++;
4805 i++;
4806 if (i%8 == 0) {
4807 printk("%4x %s\n", (i-8)*4, hex_buffer);
4808 haddr = 0;
4809 }
4810 }
4811 printk("------------------------\n");
4812} /* DumpLong */
4813
4814#endif
4815
4816static int __devinit skge_probe_one(struct pci_dev *pdev,
4817 const struct pci_device_id *ent)
4818{
4819 SK_AC *pAC;
4820 DEV_NET *pNet = NULL;
4821 struct net_device *dev = NULL;
4822 static int boards_found = 0;
4823 int error = -ENODEV;
4824 int using_dac = 0;
4825 char DeviceStr[80];
4826
4827 if (pci_enable_device(pdev))
4828 goto out;
4829
4830 /* Configure DMA attributes. */
4831 if (sizeof(dma_addr_t) > sizeof(u32) &&
4832 !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
4833 using_dac = 1;
4834 error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
4835 if (error < 0) {
4836 printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA "
4837 "for consistent allocations\n", pci_name(pdev));
4838 goto out_disable_device;
4839 }
4840 } else {
4841 error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
4842 if (error) {
4843 printk(KERN_ERR "sk98lin %s no usable DMA configuration\n",
4844 pci_name(pdev));
4845 goto out_disable_device;
4846 }
4847 }
4848
4849 error = -ENOMEM;
4850 dev = alloc_etherdev(sizeof(DEV_NET));
4851 if (!dev) {
4852 printk(KERN_ERR "sk98lin: unable to allocate etherdev "
4853 "structure!\n");
4854 goto out_disable_device;
4855 }
4856
4857 pNet = netdev_priv(dev);
4858 pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL);
4859 if (!pNet->pAC) {
4860 printk(KERN_ERR "sk98lin: unable to allocate adapter "
4861 "structure!\n");
4862 goto out_free_netdev;
4863 }
4864
4865 pAC = pNet->pAC;
4866 pAC->PciDev = pdev;
4867
4868 pAC->dev[0] = dev;
4869 pAC->dev[1] = dev;
4870 pAC->CheckQueue = SK_FALSE;
4871
4872 dev->irq = pdev->irq;
4873
4874 error = SkGeInitPCI(pAC);
4875 if (error) {
4876 printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
4877 goto out_free_netdev;
4878 }
4879
4880 dev->open = &SkGeOpen;
4881 dev->stop = &SkGeClose;
4882 dev->hard_start_xmit = &SkGeXmit;
4883 dev->get_stats = &SkGeStats;
4884 dev->set_multicast_list = &SkGeSetRxMode;
4885 dev->set_mac_address = &SkGeSetMacAddr;
4886 dev->do_ioctl = &SkGeIoctl;
4887 dev->change_mtu = &SkGeChangeMtu;
4888#ifdef CONFIG_NET_POLL_CONTROLLER
4889 dev->poll_controller = &SkGePollController;
4890#endif
4891 SET_NETDEV_DEV(dev, &pdev->dev);
4892 SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
4893
4894 /* Use only if yukon hardware */
4895 if (pAC->ChipsetType) {
4896#ifdef USE_SK_TX_CHECKSUM
4897 dev->features |= NETIF_F_IP_CSUM;
4898#endif
4899#ifdef SK_ZEROCOPY
4900 dev->features |= NETIF_F_SG;
4901#endif
4902#ifdef USE_SK_RX_CHECKSUM
4903 pAC->RxPort[0].RxCsum = 1;
4904#endif
4905 }
4906
4907 if (using_dac)
4908 dev->features |= NETIF_F_HIGHDMA;
4909
4910 pAC->Index = boards_found++;
4911
4912 error = SkGeBoardInit(dev, pAC);
4913 if (error)
4914 goto out_free_netdev;
4915
4916 /* Read Adapter name from VPD */
4917 if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
4918 error = -EIO;
4919 printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
4920 goto out_free_resources;
4921 }
4922
4923 /* Register net device */
4924 error = register_netdev(dev);
4925 if (error) {
4926 printk(KERN_ERR "sk98lin: Could not register device.\n");
4927 goto out_free_resources;
4928 }
4929
4930 /* Print adapter specific string from vpd */
4931 printk("%s: %s\n", dev->name, DeviceStr);
4932
4933 /* Print configuration settings */
4934 printk(" PrefPort:%c RlmtMode:%s\n",
4935 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
4936 (pAC->RlmtMode==0) ? "Check Link State" :
4937 ((pAC->RlmtMode==1) ? "Check Link State" :
4938 ((pAC->RlmtMode==3) ? "Check Local Port" :
4939 ((pAC->RlmtMode==7) ? "Check Segmentation" :
4940 ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
4941
4942 SkGeYellowLED(pAC, pAC->IoBase, 1);
4943
4944 memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
4945 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
4946
4947 pNet->PortNr = 0;
4948 pNet->NetNr = 0;
4949
4950 boards_found++;
4951
4952 pci_set_drvdata(pdev, dev);
4953
4954 /* More then one port found */
4955 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
4956 dev = alloc_etherdev(sizeof(DEV_NET));
4957 if (!dev) {
4958 printk(KERN_ERR "sk98lin: unable to allocate etherdev "
4959 "structure!\n");
4960 goto single_port;
4961 }
4962
4963 pNet = netdev_priv(dev);
4964 pNet->PortNr = 1;
4965 pNet->NetNr = 1;
4966 pNet->pAC = pAC;
4967
4968 dev->open = &SkGeOpen;
4969 dev->stop = &SkGeClose;
4970 dev->hard_start_xmit = &SkGeXmit;
4971 dev->get_stats = &SkGeStats;
4972 dev->set_multicast_list = &SkGeSetRxMode;
4973 dev->set_mac_address = &SkGeSetMacAddr;
4974 dev->do_ioctl = &SkGeIoctl;
4975 dev->change_mtu = &SkGeChangeMtu;
4976 SET_NETDEV_DEV(dev, &pdev->dev);
4977 SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
4978
4979 if (pAC->ChipsetType) {
4980#ifdef USE_SK_TX_CHECKSUM
4981 dev->features |= NETIF_F_IP_CSUM;
4982#endif
4983#ifdef SK_ZEROCOPY
4984 dev->features |= NETIF_F_SG;
4985#endif
4986#ifdef USE_SK_RX_CHECKSUM
4987 pAC->RxPort[1].RxCsum = 1;
4988#endif
4989 }
4990
4991 if (using_dac)
4992 dev->features |= NETIF_F_HIGHDMA;
4993
4994 error = register_netdev(dev);
4995 if (error) {
4996 printk(KERN_ERR "sk98lin: Could not register device"
4997 " for second port. (%d)\n", error);
4998 free_netdev(dev);
4999 goto single_port;
5000 }
5001
5002 pAC->dev[1] = dev;
5003 memcpy(&dev->dev_addr,
5004 &pAC->Addr.Net[1].CurrentMacAddress, 6);
5005 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
5006
5007 printk("%s: %s\n", dev->name, DeviceStr);
5008 printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
5009 }
5010
5011single_port:
5012
5013 /* Save the hardware revision */
5014 pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
5015 (pAC->GIni.GIPciHwRev & 0x0F);
5016
5017 /* Set driver globals */
5018 pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME;
5019 pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
5020
5021 memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
5022 memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
5023
5024 return 0;
5025
5026 out_free_resources:
5027 FreeResources(dev);
5028 out_free_netdev:
5029 free_netdev(dev);
5030 out_disable_device:
5031 pci_disable_device(pdev);
5032 out:
5033 return error;
5034}
5035
5036static void __devexit skge_remove_one(struct pci_dev *pdev)
5037{
5038 struct net_device *dev = pci_get_drvdata(pdev);
5039 DEV_NET *pNet = netdev_priv(dev);
5040 SK_AC *pAC = pNet->pAC;
5041 struct net_device *otherdev = pAC->dev[1];
5042
5043 unregister_netdev(dev);
5044
5045 SkGeYellowLED(pAC, pAC->IoBase, 0);
5046
5047 if (pAC->BoardLevel == SK_INIT_RUN) {
5048 SK_EVPARA EvPara;
5049 unsigned long Flags;
5050
5051 /* board is still alive */
5052 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
5053 EvPara.Para32[0] = 0;
5054 EvPara.Para32[1] = -1;
5055 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5056 EvPara.Para32[0] = 1;
5057 EvPara.Para32[1] = -1;
5058 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5059 SkEventDispatcher(pAC, pAC->IoBase);
5060 /* disable interrupts */
5061 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
5062 SkGeDeInit(pAC, pAC->IoBase);
5063 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
5064 pAC->BoardLevel = SK_INIT_DATA;
5065 /* We do NOT check here, if IRQ was pending, of course*/
5066 }
5067
5068 if (pAC->BoardLevel == SK_INIT_IO) {
5069 /* board is still alive */
5070 SkGeDeInit(pAC, pAC->IoBase);
5071 pAC->BoardLevel = SK_INIT_DATA;
5072 }
5073
5074 FreeResources(dev);
5075 free_netdev(dev);
5076 if (otherdev != dev)
5077 free_netdev(otherdev);
5078 kfree(pAC);
5079}
5080
5081#ifdef CONFIG_PM
5082static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
5083{
5084 struct net_device *dev = pci_get_drvdata(pdev);
5085 DEV_NET *pNet = netdev_priv(dev);
5086 SK_AC *pAC = pNet->pAC;
5087 struct net_device *otherdev = pAC->dev[1];
5088
5089 if (netif_running(dev)) {
5090 netif_carrier_off(dev);
5091 DoPrintInterfaceChange = SK_FALSE;
5092 SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */
5093 netif_device_detach(dev);
5094 }
5095 if (otherdev != dev) {
5096 if (netif_running(otherdev)) {
5097 netif_carrier_off(otherdev);
5098 DoPrintInterfaceChange = SK_FALSE;
5099 SkDrvDeInitAdapter(pAC, 1); /* performs SkGeClose */
5100 netif_device_detach(otherdev);
5101 }
5102 }
5103
5104 pci_save_state(pdev);
5105 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
5106 if (pAC->AllocFlag & SK_ALLOC_IRQ) {
5107 free_irq(dev->irq, dev);
5108 }
5109 pci_disable_device(pdev);
5110 pci_set_power_state(pdev, pci_choose_state(pdev, state));
5111
5112 return 0;
5113}
5114
5115static int skge_resume(struct pci_dev *pdev)
5116{
5117 struct net_device *dev = pci_get_drvdata(pdev);
5118 DEV_NET *pNet = netdev_priv(dev);
5119 SK_AC *pAC = pNet->pAC;
5120 struct net_device *otherdev = pAC->dev[1];
5121 int ret;
5122
5123 pci_set_power_state(pdev, PCI_D0);
5124 pci_restore_state(pdev);
5125 ret = pci_enable_device(pdev);
5126 if (ret) {
5127 printk(KERN_WARNING "sk98lin: unable to enable device %s "
5128 "in resume\n", dev->name);
5129 goto err_out;
5130 }
5131 pci_set_master(pdev);
5132 if (pAC->GIni.GIMacsFound == 2)
5133 ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
5134 else
5135 ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev);
5136 if (ret) {
5137 printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
5138 ret = -EBUSY;
5139 goto err_out_disable_pdev;
5140 }
5141
5142 netif_device_attach(dev);
5143 if (netif_running(dev)) {
5144 DoPrintInterfaceChange = SK_FALSE;
5145 SkDrvInitAdapter(pAC, 0); /* first device */
5146 }
5147 if (otherdev != dev) {
5148 netif_device_attach(otherdev);
5149 if (netif_running(otherdev)) {
5150 DoPrintInterfaceChange = SK_FALSE;
5151 SkDrvInitAdapter(pAC, 1); /* second device */
5152 }
5153 }
5154
5155 return 0;
5156
5157err_out_disable_pdev:
5158 pci_disable_device(pdev);
5159err_out:
5160 pAC->AllocFlag &= ~SK_ALLOC_IRQ;
5161 dev->irq = 0;
5162 return ret;
5163}
5164#else
5165#define skge_suspend NULL
5166#define skge_resume NULL
5167#endif
5168
5169static struct pci_device_id skge_pci_tbl[] = {
5170#ifdef SK98LIN_ALL_DEVICES
5171 { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5172 { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5173#endif
5174#ifdef GENESIS
5175 /* Generic SysKonnect SK-98xx Gigabit Ethernet Server Adapter */
5176 { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5177#endif
5178 /* Generic SysKonnect SK-98xx V2.0 Gigabit Ethernet Adapter */
5179 { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5180#ifdef SK98LIN_ALL_DEVICES
5181/* DLink card does not have valid VPD so this driver gags
5182 * { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5183 */
5184 { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5185 { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5186 { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5187 { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
5188 { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5189#endif
5190 { 0 }
5191};
5192
5193MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
5194
5195static struct pci_driver skge_driver = {
5196 .name = "sk98lin",
5197 .id_table = skge_pci_tbl,
5198 .probe = skge_probe_one,
5199 .remove = __devexit_p(skge_remove_one),
5200 .suspend = skge_suspend,
5201 .resume = skge_resume,
5202};
5203
5204static int __init skge_init(void)
5205{
5206 printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver"
5207 " and is scheduled for removal\n");
5208
5209 return pci_register_driver(&skge_driver);
5210}
5211
5212static void __exit skge_exit(void)
5213{
5214 pci_unregister_driver(&skge_driver);
5215}
5216
5217module_init(skge_init);
5218module_exit(skge_exit);
diff --git a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
deleted file mode 100644
index db670993c2df..000000000000
--- a/drivers/net/sk98lin/skgehwt.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgehwt.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.15 $
6 * Date: $Date: 2003/09/16 13:41:23 $
7 * Purpose: Hardware Timer
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * Event queue and dispatcher
27 */
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
35
36#ifdef __C2MAN__
37/*
38 * Hardware Timer function queue management.
39 */
40intro()
41{}
42#endif
43
44/*
45 * Prototypes of local functions.
46 */
47#define SK_HWT_MAX (65000)
48
49/* correction factor */
50#define SK_HWT_FAC (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
51
52/*
53 * Initialize hardware timer.
54 *
55 * Must be called during init level 1.
56 */
57void SkHwtInit(
58SK_AC *pAC, /* Adapters context */
59SK_IOC Ioc) /* IoContext */
60{
61 pAC->Hwt.TStart = 0 ;
62 pAC->Hwt.TStop = 0 ;
63 pAC->Hwt.TActive = SK_FALSE;
64
65 SkHwtStop(pAC, Ioc);
66}
67
68/*
69 *
70 * Start hardware timer (clock ticks are 16us).
71 *
72 */
73void SkHwtStart(
74SK_AC *pAC, /* Adapters context */
75SK_IOC Ioc, /* IoContext */
76SK_U32 Time) /* Time in units of 16us to load the timer with. */
77{
78 SK_U32 Cnt;
79
80 if (Time > SK_HWT_MAX)
81 Time = SK_HWT_MAX;
82
83 pAC->Hwt.TStart = Time;
84 pAC->Hwt.TStop = 0L;
85
86 Cnt = Time;
87
88 /*
89 * if time < 16 us
90 * time = 16 us
91 */
92 if (!Cnt) {
93 Cnt++;
94 }
95
96 SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
97
98 SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */
99
100 pAC->Hwt.TActive = SK_TRUE;
101}
102
103/*
104 * Stop hardware timer.
105 * and clear the timer IRQ
106 */
107void SkHwtStop(
108SK_AC *pAC, /* Adapters context */
109SK_IOC Ioc) /* IoContext */
110{
111 SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
112
113 SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
114
115 pAC->Hwt.TActive = SK_FALSE;
116}
117
118
119/*
120 * Stop hardware timer and read time elapsed since last start.
121 *
122 * returns
123 * The elapsed time since last start in units of 16us.
124 *
125 */
126SK_U32 SkHwtRead(
127SK_AC *pAC, /* Adapters context */
128SK_IOC Ioc) /* IoContext */
129{
130 SK_U32 TRead;
131 SK_U32 IStatus;
132
133 if (pAC->Hwt.TActive) {
134
135 SkHwtStop(pAC, Ioc);
136
137 SK_IN32(Ioc, B2_TI_VAL, &TRead);
138 TRead /= SK_HWT_FAC;
139
140 SK_IN32(Ioc, B0_ISRC, &IStatus);
141
142 /* Check if timer expired (or wraped around) */
143 if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
144
145 SkHwtStop(pAC, Ioc);
146
147 pAC->Hwt.TStop = pAC->Hwt.TStart;
148 }
149 else {
150
151 pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
152 }
153 }
154 return(pAC->Hwt.TStop);
155}
156
157/*
158 * interrupt source= timer
159 */
160void SkHwtIsr(
161SK_AC *pAC, /* Adapters context */
162SK_IOC Ioc) /* IoContext */
163{
164 SkHwtStop(pAC, Ioc);
165
166 pAC->Hwt.TStop = pAC->Hwt.TStart;
167
168 SkTimerDone(pAC, Ioc);
169}
170
171/* End of file */
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
deleted file mode 100644
index 67f1d6a5c15d..000000000000
--- a/drivers/net/sk98lin/skgeinit.c
+++ /dev/null
@@ -1,2005 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgeinit.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.97 $
6 * Date: $Date: 2003/10/02 16:45:31 $
7 * Purpose: Contains functions to initialize the adapter
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#include "h/skdrv1st.h"
26#include "h/skdrv2nd.h"
27
28/* global variables ***********************************************************/
29
30/* local variables ************************************************************/
31
32#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
33static const char SysKonnectFileId[] =
34 "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
35#endif
36
37struct s_QOffTab {
38 int RxQOff; /* Receive Queue Address Offset */
39 int XsQOff; /* Sync Tx Queue Address Offset */
40 int XaQOff; /* Async Tx Queue Address Offset */
41};
42static struct s_QOffTab QOffTab[] = {
43 {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
44};
45
46struct s_Config {
47 char ScanString[8];
48 SK_U32 Value;
49};
50
51static struct s_Config OemConfig = {
52 {'O','E','M','_','C','o','n','f'},
53#ifdef SK_OEM_CONFIG
54 OEM_CONFIG_VALUE,
55#else
56 0,
57#endif
58};
59
60/******************************************************************************
61 *
62 * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
63 *
64 * Description:
65 * Enable or disable the descriptor polling of the transmit descriptor
66 * ring(s) (TxD) for port 'Port'.
67 * The new configuration is *not* saved over any SkGeStopPort() and
68 * SkGeInitPort() calls.
69 *
70 * Returns:
71 * nothing
72 */
73void SkGePollTxD(
74SK_AC *pAC, /* adapter context */
75SK_IOC IoC, /* IO context */
76int Port, /* Port Index (MAC_1 + n) */
77SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
78{
79 SK_GEPORT *pPrt;
80 SK_U32 DWord;
81
82 pPrt = &pAC->GIni.GP[Port];
83
84 DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL);
85
86 if (pPrt->PXSQSize != 0) {
87 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
88 }
89
90 if (pPrt->PXAQSize != 0) {
91 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
92 }
93} /* SkGePollTxD */
94
95
96/******************************************************************************
97 *
98 * SkGeYellowLED() - Switch the yellow LED on or off.
99 *
100 * Description:
101 * Switch the yellow LED on or off.
102 *
103 * Note:
104 * This function may be called any time after SkGeInit(Level 1).
105 *
106 * Returns:
107 * nothing
108 */
109void SkGeYellowLED(
110SK_AC *pAC, /* adapter context */
111SK_IOC IoC, /* IO context */
112int State) /* yellow LED state, 0 = OFF, 0 != ON */
113{
114 if (State == 0) {
115 /* Switch yellow LED OFF */
116 SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
117 }
118 else {
119 /* Switch yellow LED ON */
120 SK_OUT8(IoC, B0_LED, LED_STAT_ON);
121 }
122} /* SkGeYellowLED */
123
124
125#if (!defined(SK_SLIM) || defined(GENESIS))
126/******************************************************************************
127 *
128 * SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
129 *
130 * Description:
131 * The Rx or Tx LED which is specified by 'Led' will be
132 * enabled, disabled or switched on in test mode.
133 *
134 * Note:
135 * 'Led' must contain the address offset of the LEDs INI register.
136 *
137 * Usage:
138 * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
139 *
140 * Returns:
141 * nothing
142 */
143void SkGeXmitLED(
144SK_AC *pAC, /* adapter context */
145SK_IOC IoC, /* IO context */
146int Led, /* offset to the LED Init Value register */
147int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
148{
149 SK_U32 LedIni;
150
151 switch (Mode) {
152 case SK_LED_ENA:
153 LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
154 SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
155 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
156 break;
157 case SK_LED_TST:
158 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
159 SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
160 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
161 break;
162 case SK_LED_DIS:
163 default:
164 /*
165 * Do NOT stop the LED Timer here. The LED might be
166 * in on state. But it needs to go off.
167 */
168 SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
169 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
170 break;
171 }
172
173 /*
174 * 1000BT: The Transmit LED is driven by the PHY.
175 * But the default LED configuration is used for
176 * Level One and Broadcom PHYs.
177 * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
178 * (In this case it has to be added here. But we will see. XXX)
179 */
180} /* SkGeXmitLED */
181#endif /* !SK_SLIM || GENESIS */
182
183
184/******************************************************************************
185 *
186 * DoCalcAddr() - Calculates the start and the end address of a queue.
187 *
188 * Description:
189 * This function calculates the start and the end address of a queue.
190 * Afterwards the 'StartVal' is incremented to the next start position.
191 * If the port is already initialized the calculated values
192 * will be checked against the configured values and an
193 * error will be returned, if they are not equal.
194 * If the port is not initialized the values will be written to
195 * *StartAdr and *EndAddr.
196 *
197 * Returns:
198 * 0: success
199 * 1: configuration error
200 */
201static int DoCalcAddr(
202SK_AC *pAC, /* adapter context */
203SK_GEPORT SK_FAR *pPrt, /* port index */
204int QuSize, /* size of the queue to configure in kB */
205SK_U32 SK_FAR *StartVal, /* start value for address calculation */
206SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */
207SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */
208{
209 SK_U32 EndVal;
210 SK_U32 NextStart;
211 int Rtv;
212
213 Rtv = 0;
214 if (QuSize == 0) {
215 EndVal = *StartVal;
216 NextStart = EndVal;
217 }
218 else {
219 EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
220 NextStart = EndVal + 1;
221 }
222
223 if (pPrt->PState >= SK_PRT_INIT) {
224 if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
225 Rtv = 1;
226 }
227 }
228 else {
229 *QuStartAddr = *StartVal;
230 *QuEndAddr = EndVal;
231 }
232
233 *StartVal = NextStart;
234 return(Rtv);
235} /* DoCalcAddr */
236
237/******************************************************************************
238 *
239 * SkGeInitAssignRamToQueues() - allocate default queue sizes
240 *
241 * Description:
242 * This function assigns the memory to the different queues and ports.
243 * When DualNet is set to SK_TRUE all ports get the same amount of memory.
244 * Otherwise the first port gets most of the memory and all the
245 * other ports just the required minimum.
246 * This function can only be called when pAC->GIni.GIRamSize and
247 * pAC->GIni.GIMacsFound have been initialized, usually this happens
248 * at init level 1
249 *
250 * Returns:
251 * 0 - ok
252 * 1 - invalid input values
253 * 2 - not enough memory
254 */
255
256int SkGeInitAssignRamToQueues(
257SK_AC *pAC, /* Adapter context */
258int ActivePort, /* Active Port in RLMT mode */
259SK_BOOL DualNet) /* adapter context */
260{
261 int i;
262 int UsedKilobytes; /* memory already assigned */
263 int ActivePortKilobytes; /* memory available for active port */
264 SK_GEPORT *pGePort;
265
266 UsedKilobytes = 0;
267
268 if (ActivePort >= pAC->GIni.GIMacsFound) {
269 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
270 ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
271 ActivePort));
272 return(1);
273 }
274 if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
275 ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
276 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
277 ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
278 pAC->GIni.GIRamSize));
279 return(2);
280 }
281
282 if (DualNet) {
283 /* every port gets the same amount of memory */
284 ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
285 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
286
287 pGePort = &pAC->GIni.GP[i];
288
289 /* take away the minimum memory for active queues */
290 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
291
292 /* receive queue gets the minimum + 80% of the rest */
293 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
294 ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
295 + SK_MIN_RXQ_SIZE;
296
297 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
298
299 /* synchronous transmit queue */
300 pGePort->PXSQSize = 0;
301
302 /* asynchronous transmit queue */
303 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
304 SK_MIN_TXQ_SIZE);
305 }
306 }
307 else {
308 /* Rlmt Mode or single link adapter */
309
310 /* Set standby queue size defaults for all standby ports */
311 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
312
313 if (i != ActivePort) {
314 pGePort = &pAC->GIni.GP[i];
315
316 pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
317 pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
318 pGePort->PXSQSize = 0;
319
320 /* Count used RAM */
321 UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
322 }
323 }
324 /* what's left? */
325 ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
326
327 /* assign it to the active port */
328 /* first take away the minimum memory */
329 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
330 pGePort = &pAC->GIni.GP[ActivePort];
331
332 /* receive queue get's the minimum + 80% of the rest */
333 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
334 (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
335
336 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
337
338 /* synchronous transmit queue */
339 pGePort->PXSQSize = 0;
340
341 /* asynchronous transmit queue */
342 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
343 SK_MIN_TXQ_SIZE;
344 }
345#ifdef VCPU
346 VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
347 pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
348#endif /* VCPU */
349
350 return(0);
351} /* SkGeInitAssignRamToQueues */
352
353/******************************************************************************
354 *
355 * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
356 *
357 * Description:
358 * This function verifies the Queue Size Configuration specified
359 * in the variables PRxQSize, PXSQSize, and PXAQSize of all
360 * used ports.
361 * This requirements must be fullfilled to have a valid configuration:
362 * - The size of all queues must not exceed GIRamSize.
363 * - The queue sizes must be specified in units of 8 kB.
364 * - The size of Rx queues of available ports must not be
365 * smaller than 16 kB.
366 * - The size of at least one Tx queue (synch. or asynch.)
367 * of available ports must not be smaller than 16 kB
368 * when Jumbo Frames are used.
369 * - The RAM start and end addresses must not be changed
370 * for ports which are already initialized.
371 * Furthermore SkGeCheckQSize() defines the Start and End Addresses
372 * of all ports and stores them into the HWAC port structure.
373 *
374 * Returns:
375 * 0: Queue Size Configuration valid
376 * 1: Queue Size Configuration invalid
377 */
378static int SkGeCheckQSize(
379SK_AC *pAC, /* adapter context */
380int Port) /* port index */
381{
382 SK_GEPORT *pPrt;
383 int i;
384 int Rtv;
385 int Rtv2;
386 SK_U32 StartAddr;
387#ifndef SK_SLIM
388 int UsedMem; /* total memory used (max. found ports) */
389#endif
390
391 Rtv = 0;
392
393#ifndef SK_SLIM
394
395 UsedMem = 0;
396 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
397 pPrt = &pAC->GIni.GP[i];
398
399 if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
400 (pPrt->PXSQSize & QZ_UNITS) != 0 ||
401 (pPrt->PXAQSize & QZ_UNITS) != 0) {
402
403 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
404 return(1);
405 }
406
407 if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
408 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
409 return(1);
410 }
411
412 /*
413 * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
414 * if Jumbo Frames are used, this size has to be >= 16 kB.
415 */
416 if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
417 (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
418 ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
419 (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
420 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
421 return(1);
422 }
423
424 UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
425 }
426
427 if (UsedMem > pAC->GIni.GIRamSize) {
428 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
429 return(1);
430 }
431#endif /* !SK_SLIM */
432
433 /* Now start address calculation */
434 StartAddr = pAC->GIni.GIRamOffs;
435 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
436 pPrt = &pAC->GIni.GP[i];
437
438 /* Calculate/Check values for the receive queue */
439 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
440 &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
441 Rtv |= Rtv2;
442
443 /* Calculate/Check values for the synchronous Tx queue */
444 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
445 &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
446 Rtv |= Rtv2;
447
448 /* Calculate/Check values for the asynchronous Tx queue */
449 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
450 &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
451 Rtv |= Rtv2;
452
453 if (Rtv) {
454 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
455 return(1);
456 }
457 }
458
459 return(0);
460} /* SkGeCheckQSize */
461
462
463#ifdef GENESIS
464/******************************************************************************
465 *
466 * SkGeInitMacArb() - Initialize the MAC Arbiter
467 *
468 * Description:
469 * This function initializes the MAC Arbiter.
470 * It must not be called if there is still an
471 * initialized or active port.
472 *
473 * Returns:
474 * nothing
475 */
476static void SkGeInitMacArb(
477SK_AC *pAC, /* adapter context */
478SK_IOC IoC) /* IO context */
479{
480 /* release local reset */
481 SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
482
483 /* configure timeout values */
484 SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
485 SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
486 SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
487 SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
488
489 SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
490 SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
491 SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
492 SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
493
494 /* recovery values are needed for XMAC II Rev. B2 only */
495 /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
496
497 /*
498 * There is no start or enable button to push, therefore
499 * the MAC arbiter is configured and enabled now.
500 */
501} /* SkGeInitMacArb */
502
503
504/******************************************************************************
505 *
506 * SkGeInitPktArb() - Initialize the Packet Arbiter
507 *
508 * Description:
509 * This function initializes the Packet Arbiter.
510 * It must not be called if there is still an
511 * initialized or active port.
512 *
513 * Returns:
514 * nothing
515 */
516static void SkGeInitPktArb(
517SK_AC *pAC, /* adapter context */
518SK_IOC IoC) /* IO context */
519{
520 /* release local reset */
521 SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
522
523 /* configure timeout values */
524 SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
525 SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
526 SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
527 SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
528
529 /*
530 * enable timeout timers if jumbo frames not used
531 * NOTE: the packet arbiter timeout interrupt is needed for
532 * half duplex hangup workaround
533 */
534 if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
535 if (pAC->GIni.GIMacsFound == 1) {
536 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
537 }
538 else {
539 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
540 }
541 }
542} /* SkGeInitPktArb */
543#endif /* GENESIS */
544
545
546/******************************************************************************
547 *
548 * SkGeInitMacFifo() - Initialize the MAC FIFOs
549 *
550 * Description:
551 * Initialize all MAC FIFOs of the specified port
552 *
553 * Returns:
554 * nothing
555 */
556static void SkGeInitMacFifo(
557SK_AC *pAC, /* adapter context */
558SK_IOC IoC, /* IO context */
559int Port) /* Port Index (MAC_1 + n) */
560{
561 SK_U16 Word;
562#ifdef VCPU
563 SK_U32 DWord;
564#endif /* VCPU */
565 /*
566 * For each FIFO:
567 * - release local reset
568 * - use default value for MAC FIFO size
569 * - setup defaults for the control register
570 * - enable the FIFO
571 */
572
573#ifdef GENESIS
574 if (pAC->GIni.GIGenesis) {
575 /* Configure Rx MAC FIFO */
576 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
577 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
578 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
579
580 /* Configure Tx MAC FIFO */
581 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
582 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
583 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
584
585 /* Enable frame flushing if jumbo frames used */
586 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
587 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
588 }
589 }
590#endif /* GENESIS */
591
592#ifdef YUKON
593 if (pAC->GIni.GIYukon) {
594 /* set Rx GMAC FIFO Flush Mask */
595 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
596
597 Word = (SK_U16)GMF_RX_CTRL_DEF;
598
599 /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
600 if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
601
602 Word &= ~GMF_RX_F_FL_ON;
603 }
604
605 /* Configure Rx MAC FIFO */
606 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
607 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
608
609 /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
610 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
611
612 /* Configure Tx MAC FIFO */
613 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
614 SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
615
616#ifdef VCPU
617 SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
618 SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
619#endif /* VCPU */
620
621 /* set Tx GMAC FIFO Almost Empty Threshold */
622/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
623 }
624#endif /* YUKON */
625
626} /* SkGeInitMacFifo */
627
628#ifdef SK_LNK_SYNC_CNT
629/******************************************************************************
630 *
631 * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
632 *
633 * Description:
634 * This function starts the Link Sync Counter of the specified
635 * port and enables the generation of an Link Sync IRQ.
636 * The Link Sync Counter may be used to detect an active link,
637 * if autonegotiation is not used.
638 *
639 * Note:
640 * o To ensure receiving the Link Sync Event the LinkSyncCounter
641 * should be initialized BEFORE clearing the XMAC's reset!
642 * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
643 * function.
644 *
645 * Returns:
646 * nothing
647 */
648void SkGeLoadLnkSyncCnt(
649SK_AC *pAC, /* adapter context */
650SK_IOC IoC, /* IO context */
651int Port, /* Port Index (MAC_1 + n) */
652SK_U32 CntVal) /* Counter value */
653{
654 SK_U32 OrgIMsk;
655 SK_U32 NewIMsk;
656 SK_U32 ISrc;
657 SK_BOOL IrqPend;
658
659 /* stop counter */
660 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
661
662 /*
663 * ASIC problem:
664 * Each time starting the Link Sync Counter an IRQ is generated
665 * by the adapter. See problem report entry from 21.07.98
666 *
667 * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ
668 * if no IRQ is already pending.
669 */
670 IrqPend = SK_FALSE;
671 SK_IN32(IoC, B0_ISRC, &ISrc);
672 SK_IN32(IoC, B0_IMSK, &OrgIMsk);
673 if (Port == MAC_1) {
674 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
675 if ((ISrc & IS_LNK_SYNC_M1) != 0) {
676 IrqPend = SK_TRUE;
677 }
678 }
679 else {
680 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
681 if ((ISrc & IS_LNK_SYNC_M2) != 0) {
682 IrqPend = SK_TRUE;
683 }
684 }
685 if (!IrqPend) {
686 SK_OUT32(IoC, B0_IMSK, NewIMsk);
687 }
688
689 /* load counter */
690 SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
691
692 /* start counter */
693 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
694
695 if (!IrqPend) {
696 /* clear the unexpected IRQ, and restore the interrupt mask */
697 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
698 SK_OUT32(IoC, B0_IMSK, OrgIMsk);
699 }
700} /* SkGeLoadLnkSyncCnt*/
701#endif /* SK_LNK_SYNC_CNT */
702
703#if defined(SK_DIAG) || defined(SK_CFG_SYNC)
704/******************************************************************************
705 *
706 * SkGeCfgSync() - Configure synchronous bandwidth for this port.
707 *
708 * Description:
709 * This function may be used to configure synchronous bandwidth
710 * to the specified port. This may be done any time after
711 * initializing the port. The configuration values are NOT saved
712 * in the HWAC port structure and will be overwritten any
713 * time when stopping and starting the port.
714 * Any values for the synchronous configuration will be ignored
715 * if the size of the synchronous queue is zero!
716 *
717 * The default configuration for the synchronous service is
718 * TXA_ENA_FSYNC. This means if the size of
719 * the synchronous queue is unequal zero but no specific
720 * synchronous bandwidth is configured, the synchronous queue
721 * will always have the 'unlimited' transmit priority!
722 *
723 * This mode will be restored if the synchronous bandwidth is
724 * deallocated ('IntTime' = 0 and 'LimCount' = 0).
725 *
726 * Returns:
727 * 0: success
728 * 1: parameter configuration error
729 * 2: try to configure quality of service although no
730 * synchronous queue is configured
731 */
732int SkGeCfgSync(
733SK_AC *pAC, /* adapter context */
734SK_IOC IoC, /* IO context */
735int Port, /* Port Index (MAC_1 + n) */
736SK_U32 IntTime, /* Interval Timer Value in units of 8ns */
737SK_U32 LimCount, /* Number of bytes to transfer during IntTime */
738int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
739{
740 int Rtv;
741
742 Rtv = 0;
743
744 /* check the parameters */
745 if (LimCount > IntTime ||
746 (LimCount == 0 && IntTime != 0) ||
747 (LimCount != 0 && IntTime == 0)) {
748
749 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
750 return(1);
751 }
752
753 if (pAC->GIni.GP[Port].PXSQSize == 0) {
754 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
755 return(2);
756 }
757
758 /* calculate register values */
759 IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
760 LimCount = LimCount / 8;
761
762 if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
763 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
764 return(1);
765 }
766
767 /*
768 * - Enable 'Force Sync' to ensure the synchronous queue
769 * has the priority while configuring the new values.
770 * - Also 'disable alloc' to ensure the settings complies
771 * to the SyncMode parameter.
772 * - Disable 'Rate Control' to configure the new values.
773 * - write IntTime and LimCount
774 * - start 'Rate Control' and disable 'Force Sync'
775 * if Interval Timer or Limit Counter not zero.
776 */
777 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
778 TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
779
780 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
781 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
782
783 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
784 (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
785
786 if (IntTime != 0 || LimCount != 0) {
787 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
788 }
789
790 return(0);
791} /* SkGeCfgSync */
792#endif /* SK_DIAG || SK_CFG_SYNC*/
793
794
795/******************************************************************************
796 *
797 * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
798 *
799 * Desccription:
800 * If the queue is used, enable and initialize it.
801 * Make sure the queue is still reset, if it is not used.
802 *
803 * Returns:
804 * nothing
805 */
806static void DoInitRamQueue(
807SK_AC *pAC, /* adapter context */
808SK_IOC IoC, /* IO context */
809int QuIoOffs, /* Queue IO Address Offset */
810SK_U32 QuStartAddr, /* Queue Start Address */
811SK_U32 QuEndAddr, /* Queue End Address */
812int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
813{
814 SK_U32 RxUpThresVal;
815 SK_U32 RxLoThresVal;
816
817 if (QuStartAddr != QuEndAddr) {
818 /* calculate thresholds, assume we have a big Rx queue */
819 RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
820 RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
821
822 /* build HW address format */
823 QuStartAddr = QuStartAddr / 8;
824 QuEndAddr = QuEndAddr / 8;
825
826 /* release local reset */
827 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
828
829 /* configure addresses */
830 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
831 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
832 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
833 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
834
835 switch (QuType) {
836 case SK_RX_SRAM_Q:
837 /* configure threshold for small Rx Queue */
838 RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
839
840 /* continue with SK_RX_BRAM_Q */
841 case SK_RX_BRAM_Q:
842 /* write threshold for Rx Queue */
843
844 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
845 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
846
847 /* the high priority threshold not used */
848 break;
849 case SK_TX_RAM_Q:
850 /*
851 * Do NOT use Store & Forward under normal operation due to
852 * performance optimization (GENESIS only).
853 * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
854 * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
855 * we NEED Store & Forward of the RAM buffer.
856 */
857 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
858 pAC->GIni.GIYukon) {
859 /* enable Store & Forward Mode for the Tx Side */
860 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
861 }
862 break;
863 }
864
865 /* set queue operational */
866 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
867 }
868 else {
869 /* ensure the queue is still disabled */
870 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
871 }
872} /* DoInitRamQueue */
873
874
875/******************************************************************************
876 *
877 * SkGeInitRamBufs() - Initialize the RAM Buffer Queues
878 *
879 * Description:
880 * Initialize all RAM Buffer Queues of the specified port
881 *
882 * Returns:
883 * nothing
884 */
885static void SkGeInitRamBufs(
886SK_AC *pAC, /* adapter context */
887SK_IOC IoC, /* IO context */
888int Port) /* Port Index (MAC_1 + n) */
889{
890 SK_GEPORT *pPrt;
891 int RxQType;
892
893 pPrt = &pAC->GIni.GP[Port];
894
895 if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
896 RxQType = SK_RX_SRAM_Q; /* small Rx Queue */
897 }
898 else {
899 RxQType = SK_RX_BRAM_Q; /* big Rx Queue */
900 }
901
902 DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
903 pPrt->PRxQRamEnd, RxQType);
904
905 DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
906 pPrt->PXsQRamEnd, SK_TX_RAM_Q);
907
908 DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
909 pPrt->PXaQRamEnd, SK_TX_RAM_Q);
910
911} /* SkGeInitRamBufs */
912
913
914/******************************************************************************
915 *
916 * SkGeInitRamIface() - Initialize the RAM Interface
917 *
918 * Description:
919 * This function initializes the Adapters RAM Interface.
920 *
921 * Note:
922 * This function is used in the diagnostics.
923 *
924 * Returns:
925 * nothing
926 */
927static void SkGeInitRamIface(
928SK_AC *pAC, /* adapter context */
929SK_IOC IoC) /* IO context */
930{
931 /* release local reset */
932 SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
933
934 /* configure timeout values */
935 SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
936 SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
937 SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
938 SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
939 SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
940 SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
941 SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
942 SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
943 SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
944 SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
945 SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
946 SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
947
948} /* SkGeInitRamIface */
949
950
951/******************************************************************************
952 *
953 * SkGeInitBmu() - Initialize the BMU state machines
954 *
955 * Description:
956 * Initialize all BMU state machines of the specified port
957 *
958 * Returns:
959 * nothing
960 */
961static void SkGeInitBmu(
962SK_AC *pAC, /* adapter context */
963SK_IOC IoC, /* IO context */
964int Port) /* Port Index (MAC_1 + n) */
965{
966 SK_GEPORT *pPrt;
967 SK_U32 RxWm;
968 SK_U32 TxWm;
969
970 pPrt = &pAC->GIni.GP[Port];
971
972 RxWm = SK_BMU_RX_WM;
973 TxWm = SK_BMU_TX_WM;
974
975 if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
976 /* for better performance */
977 RxWm /= 2;
978 TxWm /= 2;
979 }
980
981 /* Rx Queue: Release all local resets and set the watermark */
982 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
983 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
984
985 /*
986 * Tx Queue: Release all local resets if the queue is used !
987 * set watermark
988 */
989 if (pPrt->PXSQSize != 0) {
990 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
991 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
992 }
993
994 if (pPrt->PXAQSize != 0) {
995 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
996 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
997 }
998 /*
999 * Do NOT enable the descriptor poll timers here, because
1000 * the descriptor addresses are not specified yet.
1001 */
1002} /* SkGeInitBmu */
1003
1004
1005/******************************************************************************
1006 *
1007 * TestStopBit() - Test the stop bit of the queue
1008 *
1009 * Description:
1010 * Stopping a queue is not as simple as it seems to be.
1011 * If descriptor polling is enabled, it may happen
1012 * that RX/TX stop is done and SV idle is NOT set.
1013 * In this case we have to issue another stop command.
1014 *
1015 * Returns:
1016 * The queues control status register
1017 */
1018static SK_U32 TestStopBit(
1019SK_AC *pAC, /* Adapter Context */
1020SK_IOC IoC, /* IO Context */
1021int QuIoOffs) /* Queue IO Address Offset */
1022{
1023 SK_U32 QuCsr; /* CSR contents */
1024
1025 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1026
1027 if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
1028 /* Stop Descriptor overridden by start command */
1029 SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
1030
1031 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1032 }
1033
1034 return(QuCsr);
1035} /* TestStopBit */
1036
1037
1038/******************************************************************************
1039 *
1040 * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
1041 *
1042 * Description:
1043 * After calling this function the descriptor rings and Rx and Tx
1044 * queues of this port may be reconfigured.
1045 *
1046 * It is possible to stop the receive and transmit path separate or
1047 * both together.
1048 *
1049 * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC.
1050 * The receive queue is still active and
1051 * the pending Rx frames may be still transferred
1052 * into the RxD.
1053 * SK_STOP_RX Stop the receive path. The tansmit path
1054 * has to be stopped once before.
1055 * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX
1056 *
1057 * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive.
1058 * SK_HARD_RST Resets the MAC and the PHY.
1059 *
1060 * Example:
1061 * 1) A Link Down event was signaled for a port. Therefore the activity
1062 * of this port should be stopped and a hardware reset should be issued
1063 * to enable the workaround of XMAC Errata #2. But the received frames
1064 * should not be discarded.
1065 * ...
1066 * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
1067 * (transfer all pending Rx frames)
1068 * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
1069 * ...
1070 *
1071 * 2) An event was issued which request the driver to switch
1072 * the 'virtual active' link to an other already active port
1073 * as soon as possible. The frames in the receive queue of this
1074 * port may be lost. But the PHY must not be reset during this
1075 * event.
1076 * ...
1077 * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
1078 * ...
1079 *
1080 * Extended Description:
1081 * If SK_STOP_TX is set,
1082 * o disable the MAC's receive and transmitter to prevent
1083 * from sending incomplete frames
1084 * o stop the port's transmit queues before terminating the
1085 * BMUs to prevent from performing incomplete PCI cycles
1086 * on the PCI bus
1087 * - The network Rx and Tx activity and PCI Tx transfer is
1088 * disabled now.
1089 * o reset the MAC depending on the RstMode
1090 * o Stop Interval Timer and Limit Counter of Tx Arbiter,
1091 * also disable Force Sync bit and Enable Alloc bit.
1092 * o perform a local reset of the port's Tx path
1093 * - reset the PCI FIFO of the async Tx queue
1094 * - reset the PCI FIFO of the sync Tx queue
1095 * - reset the RAM Buffer async Tx queue
1096 * - reset the RAM Buffer sync Tx queue
1097 * - reset the MAC Tx FIFO
1098 * o switch Link and Tx LED off, stop the LED counters
1099 *
1100 * If SK_STOP_RX is set,
1101 * o stop the port's receive queue
1102 * - The path data transfer activity is fully stopped now.
1103 * o perform a local reset of the port's Rx path
1104 * - reset the PCI FIFO of the Rx queue
1105 * - reset the RAM Buffer receive queue
1106 * - reset the MAC Rx FIFO
1107 * o switch Rx LED off, stop the LED counter
1108 *
1109 * If all ports are stopped,
1110 * o reset the RAM Interface.
1111 *
1112 * Notes:
1113 * o This function may be called during the driver states RESET_PORT and
1114 * SWITCH_PORT.
1115 */
1116void SkGeStopPort(
1117SK_AC *pAC, /* adapter context */
1118SK_IOC IoC, /* I/O context */
1119int Port, /* port to stop (MAC_1 + n) */
1120int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
1121int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
1122{
1123#ifndef SK_DIAG
1124 SK_EVPARA Para;
1125#endif /* !SK_DIAG */
1126 SK_GEPORT *pPrt;
1127 SK_U32 DWord;
1128 SK_U32 XsCsr;
1129 SK_U32 XaCsr;
1130 SK_U64 ToutStart;
1131 int i;
1132 int ToutCnt;
1133
1134 pPrt = &pAC->GIni.GP[Port];
1135
1136 if ((Dir & SK_STOP_TX) != 0) {
1137 /* disable receiver and transmitter */
1138 SkMacRxTxDisable(pAC, IoC, Port);
1139
1140 /* stop both transmit queues */
1141 /*
1142 * If the BMU is in the reset state CSR_STOP will terminate
1143 * immediately.
1144 */
1145 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
1146 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
1147
1148 ToutStart = SkOsGetTime(pAC);
1149 ToutCnt = 0;
1150 do {
1151 /*
1152 * Clear packet arbiter timeout to make sure
1153 * this loop will terminate.
1154 */
1155 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1156 PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
1157
1158 /*
1159 * If the transfer stucks at the MAC the STOP command will not
1160 * terminate if we don't flush the XMAC's transmit FIFO !
1161 */
1162 SkMacFlushTxFifo(pAC, IoC, Port);
1163
1164 XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
1165 XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
1166
1167 if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
1168 /*
1169 * Timeout of 1/18 second reached.
1170 * This needs to be checked at 1/18 sec only.
1171 */
1172 ToutCnt++;
1173 if (ToutCnt > 1) {
1174 /* Might be a problem when the driver event handler
1175 * calls StopPort again. XXX.
1176 */
1177
1178 /* Fatal Error, Loop aborted */
1179 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
1180 SKERR_HWI_E018MSG);
1181#ifndef SK_DIAG
1182 Para.Para64 = Port;
1183 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
1184#endif /* !SK_DIAG */
1185 return;
1186 }
1187 /*
1188 * Cache incoherency workaround: Assume a start command
1189 * has been lost while sending the frame.
1190 */
1191 ToutStart = SkOsGetTime(pAC);
1192
1193 if ((XsCsr & CSR_STOP) != 0) {
1194 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
1195 }
1196 if ((XaCsr & CSR_STOP) != 0) {
1197 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
1198 }
1199 }
1200
1201 /*
1202 * Because of the ASIC problem report entry from 21.08.1998 it is
1203 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
1204 */
1205 } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
1206 (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1207
1208 /* Reset the MAC depending on the RstMode */
1209 if (RstMode == SK_SOFT_RST) {
1210 SkMacSoftRst(pAC, IoC, Port);
1211 }
1212 else {
1213 SkMacHardRst(pAC, IoC, Port);
1214 }
1215
1216 /* Disable Force Sync bit and Enable Alloc bit */
1217 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
1218 TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
1219
1220 /* Stop Interval Timer and Limit Counter of Tx Arbiter */
1221 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
1222 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
1223
1224 /* Perform a local reset of the port's Tx path */
1225
1226 /* Reset the PCI FIFO of the async Tx queue */
1227 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
1228 /* Reset the PCI FIFO of the sync Tx queue */
1229 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
1230 /* Reset the RAM Buffer async Tx queue */
1231 SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
1232 /* Reset the RAM Buffer sync Tx queue */
1233 SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
1234
1235 /* Reset Tx MAC FIFO */
1236#ifdef GENESIS
1237 if (pAC->GIni.GIGenesis) {
1238 /* Note: MFF_RST_SET does NOT reset the XMAC ! */
1239 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
1240
1241 /* switch Link and Tx LED off, stop the LED counters */
1242 /* Link LED is switched off by the RLMT and the Diag itself */
1243 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
1244 }
1245#endif /* GENESIS */
1246
1247#ifdef YUKON
1248 if (pAC->GIni.GIYukon) {
1249 /* Reset TX MAC FIFO */
1250 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1251 }
1252#endif /* YUKON */
1253 }
1254
1255 if ((Dir & SK_STOP_RX) != 0) {
1256 /*
1257 * The RX Stop Command will not terminate if no buffers
1258 * are queued in the RxD ring. But it will always reach
1259 * the Idle state. Therefore we can use this feature to
1260 * stop the transfer of received packets.
1261 */
1262 /* stop the port's receive queue */
1263 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
1264
1265 i = 100;
1266 do {
1267 /*
1268 * Clear packet arbiter timeout to make sure
1269 * this loop will terminate
1270 */
1271 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1272 PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
1273
1274 DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
1275
1276 /* timeout if i==0 (bug fix for #10748) */
1277 if (--i == 0) {
1278 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
1279 SKERR_HWI_E024MSG);
1280 break;
1281 }
1282 /*
1283 * because of the ASIC problem report entry from 21.08.98
1284 * it is required to wait until CSR_STOP is reset and
1285 * CSR_SV_IDLE is set.
1286 */
1287 } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1288
1289 /* The path data transfer activity is fully stopped now */
1290
1291 /* Perform a local reset of the port's Rx path */
1292
1293 /* Reset the PCI FIFO of the Rx queue */
1294 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
1295 /* Reset the RAM Buffer receive queue */
1296 SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
1297
1298 /* Reset Rx MAC FIFO */
1299#ifdef GENESIS
1300 if (pAC->GIni.GIGenesis) {
1301
1302 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
1303
1304 /* switch Rx LED off, stop the LED counter */
1305 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
1306 }
1307#endif /* GENESIS */
1308
1309#ifdef YUKON
1310 if (pAC->GIni.GIYukon) {
1311 /* Reset Rx MAC FIFO */
1312 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1313 }
1314#endif /* YUKON */
1315 }
1316} /* SkGeStopPort */
1317
1318
1319/******************************************************************************
1320 *
1321 * SkGeInit0() - Level 0 Initialization
1322 *
1323 * Description:
1324 * - Initialize the BMU address offsets
1325 *
1326 * Returns:
1327 * nothing
1328 */
1329static void SkGeInit0(
1330SK_AC *pAC, /* adapter context */
1331SK_IOC IoC) /* IO context */
1332{
1333 int i;
1334 SK_GEPORT *pPrt;
1335
1336 for (i = 0; i < SK_MAX_MACS; i++) {
1337 pPrt = &pAC->GIni.GP[i];
1338
1339 pPrt->PState = SK_PRT_RESET;
1340 pPrt->PRxQOff = QOffTab[i].RxQOff;
1341 pPrt->PXsQOff = QOffTab[i].XsQOff;
1342 pPrt->PXaQOff = QOffTab[i].XaQOff;
1343 pPrt->PCheckPar = SK_FALSE;
1344 pPrt->PIsave = 0;
1345 pPrt->PPrevShorts = 0;
1346 pPrt->PLinkResCt = 0;
1347 pPrt->PAutoNegTOCt = 0;
1348 pPrt->PPrevRx = 0;
1349 pPrt->PPrevFcs = 0;
1350 pPrt->PRxLim = SK_DEF_RX_WA_LIM;
1351 pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
1352 pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS;
1353 pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS;
1354 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN;
1355 pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE;
1356 pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1357 pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
1358 SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
1359 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
1360 pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1361 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
1362 pPrt->PMSCap = 0;
1363 pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO;
1364 pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET;
1365 pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
1366 pPrt->PAutoNegFail = SK_FALSE;
1367 pPrt->PHWLinkUp = SK_FALSE;
1368 pPrt->PLinkBroken = SK_TRUE; /* See WA code */
1369 pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
1370 pPrt->PMacColThres = TX_COL_DEF;
1371 pPrt->PMacJamLen = TX_JAM_LEN_DEF;
1372 pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF;
1373 pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
1374 pPrt->PMacIpgData = IPG_DATA_DEF;
1375 pPrt->PMacLimit4 = SK_FALSE;
1376 }
1377
1378 pAC->GIni.GIPortUsage = SK_RED_LINK;
1379 pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
1380 pAC->GIni.GIValIrqMask = IS_ALL_MSK;
1381
1382} /* SkGeInit0*/
1383
1384
1385/******************************************************************************
1386 *
1387 * SkGeInit1() - Level 1 Initialization
1388 *
1389 * Description:
1390 * o Do a software reset.
1391 * o Clear all reset bits.
1392 * o Verify that the detected hardware is present.
1393 * Return an error if not.
1394 * o Get the hardware configuration
1395 * + Read the number of MACs/Ports.
1396 * + Read the RAM size.
1397 * + Read the PCI Revision Id.
1398 * + Find out the adapters host clock speed
1399 * + Read and check the PHY type
1400 *
1401 * Returns:
1402 * 0: success
1403 * 5: Unexpected PHY type detected
1404 * 6: HW self test failed
1405 */
1406static int SkGeInit1(
1407SK_AC *pAC, /* adapter context */
1408SK_IOC IoC) /* IO context */
1409{
1410 SK_U8 Byte;
1411 SK_U16 Word;
1412 SK_U16 CtrlStat;
1413 SK_U32 DWord;
1414 int RetVal;
1415 int i;
1416
1417 RetVal = 0;
1418
1419 /* save CLK_RUN bits (YUKON-Lite) */
1420 SK_IN16(IoC, B0_CTST, &CtrlStat);
1421
1422 /* do the SW-reset */
1423 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
1424
1425 /* release the SW-reset */
1426 SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
1427
1428 /* reset all error bits in the PCI STATUS register */
1429 /*
1430 * Note: PCI Cfg cycles cannot be used, because they are not
1431 * available on some platforms after 'boot time'.
1432 */
1433 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
1434
1435 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
1436 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
1437 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
1438
1439 /* release Master Reset */
1440 SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
1441
1442#ifdef CLK_RUN
1443 CtrlStat |= CS_CLK_RUN_ENA;
1444#endif /* CLK_RUN */
1445
1446 /* restore CLK_RUN bits */
1447 SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
1448 (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
1449
1450 /* read Chip Identification Number */
1451 SK_IN8(IoC, B2_CHIP_ID, &Byte);
1452 pAC->GIni.GIChipId = Byte;
1453
1454 /* read number of MACs */
1455 SK_IN8(IoC, B2_MAC_CFG, &Byte);
1456 pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
1457
1458 /* get Chip Revision Number */
1459 pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
1460
1461 /* get diff. PCI parameters */
1462 SK_IN16(IoC, B0_CTST, &CtrlStat);
1463
1464 /* read the adapters RAM size */
1465 SK_IN8(IoC, B2_E_0, &Byte);
1466
1467 pAC->GIni.GIGenesis = SK_FALSE;
1468 pAC->GIni.GIYukon = SK_FALSE;
1469 pAC->GIni.GIYukonLite = SK_FALSE;
1470
1471#ifdef GENESIS
1472 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
1473
1474 pAC->GIni.GIGenesis = SK_TRUE;
1475
1476 if (Byte == (SK_U8)3) {
1477 /* special case: 4 x 64k x 36, offset = 0x80000 */
1478 pAC->GIni.GIRamSize = 1024;
1479 pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
1480 }
1481 else {
1482 pAC->GIni.GIRamSize = (int)Byte * 512;
1483 pAC->GIni.GIRamOffs = 0;
1484 }
1485 /* all GE adapters work with 53.125 MHz host clock */
1486 pAC->GIni.GIHstClkFact = SK_FACT_53;
1487
1488 /* set Descr. Poll Timer Init Value to 250 ms */
1489 pAC->GIni.GIPollTimerVal =
1490 SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1491 }
1492#endif /* GENESIS */
1493
1494#ifdef YUKON
1495 if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
1496
1497 pAC->GIni.GIYukon = SK_TRUE;
1498
1499 pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
1500
1501 pAC->GIni.GIRamOffs = 0;
1502
1503 /* WA for chip Rev. A */
1504 pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
1505 pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
1506
1507 /* get PM Capabilities of PCI config space */
1508 SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
1509
1510 /* check if VAUX is available */
1511 if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
1512 /* check also if PME from D3cold is set */
1513 ((Word & PCI_PME_D3C_SUP) != 0)) {
1514 /* set entry in GE init struct */
1515 pAC->GIni.GIVauxAvail = SK_TRUE;
1516 }
1517
1518 if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
1519 /* this is Rev. A1 */
1520 pAC->GIni.GIYukonLite = SK_TRUE;
1521 }
1522 else {
1523 /* save Flash-Address Register */
1524 SK_IN32(IoC, B2_FAR, &DWord);
1525
1526 /* test Flash-Address Register */
1527 SK_OUT8(IoC, B2_FAR + 3, 0xff);
1528 SK_IN8(IoC, B2_FAR + 3, &Byte);
1529
1530 if (Byte != 0) {
1531 /* this is Rev. A0 */
1532 pAC->GIni.GIYukonLite = SK_TRUE;
1533
1534 /* restore Flash-Address Register */
1535 SK_OUT32(IoC, B2_FAR, DWord);
1536 }
1537 }
1538
1539 /* switch power to VCC (WA for VAUX problem) */
1540 SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
1541 PC_VAUX_OFF | PC_VCC_ON));
1542
1543 /* read the Interrupt source */
1544 SK_IN32(IoC, B0_ISRC, &DWord);
1545
1546 if ((DWord & IS_HW_ERR) != 0) {
1547 /* read the HW Error Interrupt source */
1548 SK_IN32(IoC, B0_HWE_ISRC, &DWord);
1549
1550 if ((DWord & IS_IRQ_SENSOR) != 0) {
1551 /* disable HW Error IRQ */
1552 pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
1553 }
1554 }
1555
1556 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1557 /* set GMAC Link Control reset */
1558 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
1559
1560 /* clear GMAC Link Control reset */
1561 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
1562 }
1563 /* all YU chips work with 78.125 MHz host clock */
1564 pAC->GIni.GIHstClkFact = SK_FACT_78;
1565
1566 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */
1567 }
1568#endif /* YUKON */
1569
1570 /* check if 64-bit PCI Slot is present */
1571 pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
1572
1573 /* check if 66 MHz PCI Clock is active */
1574 pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
1575
1576 /* read PCI HW Revision Id. */
1577 SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
1578 pAC->GIni.GIPciHwRev = Byte;
1579
1580 /* read the PMD type */
1581 SK_IN8(IoC, B2_PMD_TYP, &Byte);
1582 pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
1583
1584 /* read the PHY type */
1585 SK_IN8(IoC, B2_E_1, &Byte);
1586
1587 Byte &= 0x0f; /* the PHY type is stored in the lower nibble */
1588 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1589
1590#ifdef GENESIS
1591 if (pAC->GIni.GIGenesis) {
1592 switch (Byte) {
1593 case SK_PHY_XMAC:
1594 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
1595 break;
1596 case SK_PHY_BCOM:
1597 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
1598 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1599 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1600 break;
1601#ifdef OTHER_PHY
1602 case SK_PHY_LONE:
1603 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
1604 break;
1605 case SK_PHY_NAT:
1606 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
1607 break;
1608#endif /* OTHER_PHY */
1609 default:
1610 /* ERROR: unexpected PHY type detected */
1611 RetVal = 5;
1612 break;
1613 }
1614 }
1615#endif /* GENESIS */
1616
1617#ifdef YUKON
1618 if (pAC->GIni.GIYukon) {
1619
1620 if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
1621 /* if this field is not initialized */
1622 Byte = (SK_U8)SK_PHY_MARV_COPPER;
1623
1624 pAC->GIni.GICopperType = SK_TRUE;
1625 }
1626
1627 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
1628
1629 if (pAC->GIni.GICopperType) {
1630
1631 pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
1632 SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
1633 SK_LSPEED_CAP_1000MBPS);
1634
1635 pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
1636
1637 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1638 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1639 }
1640 else {
1641 Byte = (SK_U8)SK_PHY_MARV_FIBER;
1642 }
1643 }
1644#endif /* YUKON */
1645
1646 pAC->GIni.GP[i].PhyType = (int)Byte;
1647
1648 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1649 ("PHY type: %d PHY addr: %04x\n", Byte,
1650 pAC->GIni.GP[i].PhyAddr));
1651 }
1652
1653 /* get MAC Type & set function pointers dependent on */
1654#ifdef GENESIS
1655 if (pAC->GIni.GIGenesis) {
1656
1657 pAC->GIni.GIMacType = SK_MAC_XMAC;
1658
1659 pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats;
1660 pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic;
1661 pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter;
1662 pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus;
1663 }
1664#endif /* GENESIS */
1665
1666#ifdef YUKON
1667 if (pAC->GIni.GIYukon) {
1668
1669 pAC->GIni.GIMacType = SK_MAC_GMAC;
1670
1671 pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats;
1672 pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic;
1673 pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter;
1674 pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus;
1675
1676#ifdef SPECIAL_HANDLING
1677 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
1678 /* check HW self test result */
1679 SK_IN8(IoC, B2_E_3, &Byte);
1680 if (Byte & B2_E3_RES_MASK) {
1681 RetVal = 6;
1682 }
1683 }
1684#endif
1685 }
1686#endif /* YUKON */
1687
1688 return(RetVal);
1689} /* SkGeInit1 */
1690
1691
1692/******************************************************************************
1693 *
1694 * SkGeInit2() - Level 2 Initialization
1695 *
1696 * Description:
1697 * - start the Blink Source Counter
1698 * - start the Descriptor Poll Timer
1699 * - configure the MAC-Arbiter
1700 * - configure the Packet-Arbiter
1701 * - enable the Tx Arbiters
1702 * - enable the RAM Interface Arbiter
1703 *
1704 * Returns:
1705 * nothing
1706 */
1707static void SkGeInit2(
1708SK_AC *pAC, /* adapter context */
1709SK_IOC IoC) /* IO context */
1710{
1711#ifdef GENESIS
1712 SK_U32 DWord;
1713#endif /* GENESIS */
1714 int i;
1715
1716 /* start the Descriptor Poll Timer */
1717 if (pAC->GIni.GIPollTimerVal != 0) {
1718 if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
1719 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
1720
1721 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
1722 }
1723 SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
1724 SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
1725 }
1726
1727#ifdef GENESIS
1728 if (pAC->GIni.GIGenesis) {
1729 /* start the Blink Source Counter */
1730 DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1731
1732 SK_OUT32(IoC, B2_BSC_INI, DWord);
1733 SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
1734
1735 /*
1736 * Configure the MAC Arbiter and the Packet Arbiter.
1737 * They will be started once and never be stopped.
1738 */
1739 SkGeInitMacArb(pAC, IoC);
1740
1741 SkGeInitPktArb(pAC, IoC);
1742 }
1743#endif /* GENESIS */
1744
1745#ifdef YUKON
1746 if (pAC->GIni.GIYukon) {
1747 /* start Time Stamp Timer */
1748 SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
1749 }
1750#endif /* YUKON */
1751
1752 /* enable the Tx Arbiters */
1753 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1754 SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
1755 }
1756
1757 /* enable the RAM Interface Arbiter */
1758 SkGeInitRamIface(pAC, IoC);
1759
1760} /* SkGeInit2 */
1761
1762/******************************************************************************
1763 *
1764 * SkGeInit() - Initialize the GE Adapter with the specified level.
1765 *
1766 * Description:
1767 * Level 0: Initialize the Module structures.
1768 * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has
1769 * to be set before calling this level.
1770 *
1771 * o Do a software reset.
1772 * o Clear all reset bits.
1773 * o Verify that the detected hardware is present.
1774 * Return an error if not.
1775 * o Get the hardware configuration
1776 * + Set GIMacsFound with the number of MACs.
1777 * + Store the RAM size in GIRamSize.
1778 * + Save the PCI Revision ID in GIPciHwRev.
1779 * o return an error
1780 * if Number of MACs > SK_MAX_MACS
1781 *
1782 * After returning from Level 0 the adapter
1783 * may be accessed with IO operations.
1784 *
1785 * Level 2: start the Blink Source Counter
1786 *
1787 * Returns:
1788 * 0: success
1789 * 1: Number of MACs exceeds SK_MAX_MACS (after level 1)
1790 * 2: Adapter not present or not accessible
1791 * 3: Illegal initialization level
1792 * 4: Initialization Level 1 Call missing
1793 * 5: Unexpected PHY type detected
1794 * 6: HW self test failed
1795 */
1796int SkGeInit(
1797SK_AC *pAC, /* adapter context */
1798SK_IOC IoC, /* IO context */
1799int Level) /* initialization level */
1800{
1801 int RetVal; /* return value */
1802 SK_U32 DWord;
1803
1804 RetVal = 0;
1805 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1806 ("SkGeInit(Level %d)\n", Level));
1807
1808 switch (Level) {
1809 case SK_INIT_DATA:
1810 /* Initialization Level 0 */
1811 SkGeInit0(pAC, IoC);
1812 pAC->GIni.GILevel = SK_INIT_DATA;
1813 break;
1814
1815 case SK_INIT_IO:
1816 /* Initialization Level 1 */
1817 RetVal = SkGeInit1(pAC, IoC);
1818 if (RetVal != 0) {
1819 break;
1820 }
1821
1822 /* check if the adapter seems to be accessible */
1823 SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
1824 SK_IN32(IoC, B2_IRQM_INI, &DWord);
1825 SK_OUT32(IoC, B2_IRQM_INI, 0L);
1826
1827 if (DWord != SK_TEST_VAL) {
1828 RetVal = 2;
1829 break;
1830 }
1831
1832 /* check if the number of GIMacsFound matches SK_MAX_MACS */
1833 if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
1834 RetVal = 1;
1835 break;
1836 }
1837
1838 /* Level 1 successfully passed */
1839 pAC->GIni.GILevel = SK_INIT_IO;
1840 break;
1841
1842 case SK_INIT_RUN:
1843 /* Initialization Level 2 */
1844 if (pAC->GIni.GILevel != SK_INIT_IO) {
1845#ifndef SK_DIAG
1846 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
1847#endif /* !SK_DIAG */
1848 RetVal = 4;
1849 break;
1850 }
1851 SkGeInit2(pAC, IoC);
1852
1853 /* Level 2 successfully passed */
1854 pAC->GIni.GILevel = SK_INIT_RUN;
1855 break;
1856
1857 default:
1858 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
1859 RetVal = 3;
1860 break;
1861 }
1862
1863 return(RetVal);
1864} /* SkGeInit */
1865
1866
1867/******************************************************************************
1868 *
1869 * SkGeDeInit() - Deinitialize the adapter
1870 *
1871 * Description:
1872 * All ports of the adapter will be stopped if not already done.
1873 * Do a software reset and switch off all LEDs.
1874 *
1875 * Returns:
1876 * nothing
1877 */
1878void SkGeDeInit(
1879SK_AC *pAC, /* adapter context */
1880SK_IOC IoC) /* IO context */
1881{
1882 int i;
1883 SK_U16 Word;
1884
1885#if (!defined(SK_SLIM) && !defined(VCPU))
1886 /* ensure I2C is ready */
1887 SkI2cWaitIrq(pAC, IoC);
1888#endif
1889
1890 /* stop all current transfer activity */
1891 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1892 if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
1893 pAC->GIni.GP[i].PState != SK_PRT_RESET) {
1894
1895 SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
1896 }
1897 }
1898
1899 /* Reset all bits in the PCI STATUS register */
1900 /*
1901 * Note: PCI Cfg cycles cannot be used, because they are not
1902 * available on some platforms after 'boot time'.
1903 */
1904 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
1905
1906 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
1907 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
1908 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
1909
1910 /* do the reset, all LEDs are switched off now */
1911 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
1912
1913 pAC->GIni.GILevel = SK_INIT_DATA;
1914} /* SkGeDeInit */
1915
1916
1917/******************************************************************************
1918 *
1919 * SkGeInitPort() Initialize the specified port.
1920 *
1921 * Description:
1922 * PRxQSize, PXSQSize, and PXAQSize has to be
1923 * configured for the specified port before calling this function.
1924 * The descriptor rings has to be initialized too.
1925 *
1926 * o (Re)configure queues of the specified port.
1927 * o configure the MAC of the specified port.
1928 * o put ASIC and MAC(s) in operational mode.
1929 * o initialize Rx/Tx and Sync LED
1930 * o initialize RAM Buffers and MAC FIFOs
1931 *
1932 * The port is ready to connect when returning.
1933 *
1934 * Note:
1935 * The MAC's Rx and Tx state machine is still disabled when returning.
1936 *
1937 * Returns:
1938 * 0: success
1939 * 1: Queue size initialization error. The configured values
1940 * for PRxQSize, PXSQSize, or PXAQSize are invalid for one
1941 * or more queues. The specified port was NOT initialized.
1942 * An error log entry was generated.
1943 * 2: The port has to be stopped before it can be initialized again.
1944 */
1945int SkGeInitPort(
1946SK_AC *pAC, /* adapter context */
1947SK_IOC IoC, /* IO context */
1948int Port) /* Port to configure */
1949{
1950 SK_GEPORT *pPrt;
1951
1952 pPrt = &pAC->GIni.GP[Port];
1953
1954 if (SkGeCheckQSize(pAC, Port) != 0) {
1955 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
1956 return(1);
1957 }
1958
1959 if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
1960 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
1961 return(2);
1962 }
1963
1964 /* configuration ok, initialize the Port now */
1965
1966#ifdef GENESIS
1967 if (pAC->GIni.GIGenesis) {
1968 /* initialize Rx, Tx and Link LED */
1969 /*
1970 * If 1000BT Phy needs LED initialization than swap
1971 * LED and XMAC initialization order
1972 */
1973 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
1974 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
1975 /* The Link LED is initialized by RLMT or Diagnostics itself */
1976
1977 SkXmInitMac(pAC, IoC, Port);
1978 }
1979#endif /* GENESIS */
1980
1981#ifdef YUKON
1982 if (pAC->GIni.GIYukon) {
1983
1984 SkGmInitMac(pAC, IoC, Port);
1985 }
1986#endif /* YUKON */
1987
1988 /* do NOT initialize the Link Sync Counter */
1989
1990 SkGeInitMacFifo(pAC, IoC, Port);
1991
1992 SkGeInitRamBufs(pAC, IoC, Port);
1993
1994 if (pPrt->PXSQSize != 0) {
1995 /* enable Force Sync bit if synchronous queue available */
1996 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
1997 }
1998
1999 SkGeInitBmu(pAC, IoC, Port);
2000
2001 /* mark port as initialized */
2002 pPrt->PState = SK_PRT_INIT;
2003
2004 return(0);
2005} /* SkGeInitPort */
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
deleted file mode 100644
index fde45083eb7b..000000000000
--- a/drivers/net/sk98lin/skgemib.c
+++ /dev/null
@@ -1,1075 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgemib.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.11 $
6 * Date: $Date: 2003/09/15 13:38:12 $
7 * Purpose: Private Network Management Interface Management Database
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * PRIVATE OID handler function prototypes
27 */
28PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action,
29 SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
30 unsigned int TableIndex, SK_U32 NetIndex);
31PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
32 char *pBuf, unsigned int *pLen, SK_U32 Instance,
33 unsigned int TableIndex, SK_U32 NetIndex);
34PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
35 char *pBuf, unsigned int *pLen, SK_U32 Instance,
36 unsigned int TableIndex, SK_U32 NetIndex);
37PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
38 char *pBuf, unsigned int *pLen, SK_U32 Instance,
39 unsigned int TableIndex, SK_U32 NetIndex);
40PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
41 char *pBuf, unsigned int *pLen, SK_U32 Instance,
42 unsigned int TableIndex, SK_U32 NetIndex);
43PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
44 char *pBuf, unsigned int *pLen, SK_U32 Instance,
45 unsigned int TableIndex, SK_U32 NetIndex);
46PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
47 SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
48 unsigned int TableIndex, SK_U32 NetIndex);
49PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
50 char *pBuf, unsigned int *pLen, SK_U32 Instance,
51 unsigned int TableIndex, SK_U32 NetIndex);
52PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
53 char *pBuf, unsigned int* pLen, SK_U32 Instance,
54 unsigned int TableIndex, SK_U32 NetIndex);
55PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
56 char *pBuf, unsigned int *pLen, SK_U32 Instance,
57 unsigned int TableIndex, SK_U32 NetIndex);
58PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
59 char *pBuf, unsigned int *pLen, SK_U32 Instance,
60 unsigned int TableIndex, SK_U32 NetIndex);
61PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
62 char *pBuf, unsigned int *pLen, SK_U32 Instance,
63 unsigned int TableIndex, SK_U32 NetIndex);
64PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
65 char *pBuf, unsigned int *pLen, SK_U32 Instance,
66 unsigned int TableIndex, SK_U32 NetIndex);
67PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
68 char *pBuf, unsigned int *pLen, SK_U32 Instance,
69 unsigned int TableIndex, SK_U32 NetIndex);
70
71#ifdef SK_POWER_MGMT
72PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
73 char *pBuf, unsigned int *pLen, SK_U32 Instance,
74 unsigned int TableIndex, SK_U32 NetIndex);
75#endif /* SK_POWER_MGMT */
76
77#ifdef SK_DIAG_SUPPORT
78PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
79 char *pBuf, unsigned int *pLen, SK_U32 Instance,
80 unsigned int TableIndex, SK_U32 NetIndex);
81#endif /* SK_DIAG_SUPPORT */
82
83
84/* defines *******************************************************************/
85#define ID_TABLE_SIZE ARRAY_SIZE(IdTable)
86
87
88/* global variables **********************************************************/
89
90/*
91 * Table to correlate OID with handler function and index to
92 * hardware register stored in StatAddress if applicable.
93 */
94PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = {
95 {OID_GEN_XMIT_OK,
96 0,
97 0,
98 0,
99 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX},
100 {OID_GEN_RCV_OK,
101 0,
102 0,
103 0,
104 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX},
105 {OID_GEN_XMIT_ERROR,
106 0,
107 0,
108 0,
109 SK_PNMI_RO, General, 0},
110 {OID_GEN_RCV_ERROR,
111 0,
112 0,
113 0,
114 SK_PNMI_RO, General, 0},
115 {OID_GEN_RCV_NO_BUFFER,
116 0,
117 0,
118 0,
119 SK_PNMI_RO, General, 0},
120 {OID_GEN_DIRECTED_FRAMES_XMIT,
121 0,
122 0,
123 0,
124 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST},
125 {OID_GEN_MULTICAST_FRAMES_XMIT,
126 0,
127 0,
128 0,
129 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST},
130 {OID_GEN_BROADCAST_FRAMES_XMIT,
131 0,
132 0,
133 0,
134 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST},
135 {OID_GEN_DIRECTED_FRAMES_RCV,
136 0,
137 0,
138 0,
139 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST},
140 {OID_GEN_MULTICAST_FRAMES_RCV,
141 0,
142 0,
143 0,
144 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST},
145 {OID_GEN_BROADCAST_FRAMES_RCV,
146 0,
147 0,
148 0,
149 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST},
150 {OID_GEN_RCV_CRC_ERROR,
151 0,
152 0,
153 0,
154 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS},
155 {OID_GEN_TRANSMIT_QUEUE_LENGTH,
156 0,
157 0,
158 0,
159 SK_PNMI_RO, General, 0},
160 {OID_802_3_PERMANENT_ADDRESS,
161 0,
162 0,
163 0,
164 SK_PNMI_RO, Mac8023Stat, 0},
165 {OID_802_3_CURRENT_ADDRESS,
166 0,
167 0,
168 0,
169 SK_PNMI_RO, Mac8023Stat, 0},
170 {OID_802_3_RCV_ERROR_ALIGNMENT,
171 0,
172 0,
173 0,
174 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING},
175 {OID_802_3_XMIT_ONE_COLLISION,
176 0,
177 0,
178 0,
179 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL},
180 {OID_802_3_XMIT_MORE_COLLISIONS,
181 0,
182 0,
183 0,
184 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL},
185 {OID_802_3_XMIT_DEFERRED,
186 0,
187 0,
188 0,
189 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL},
190 {OID_802_3_XMIT_MAX_COLLISIONS,
191 0,
192 0,
193 0,
194 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL},
195 {OID_802_3_RCV_OVERRUN,
196 0,
197 0,
198 0,
199 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW},
200 {OID_802_3_XMIT_UNDERRUN,
201 0,
202 0,
203 0,
204 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN},
205 {OID_802_3_XMIT_TIMES_CRS_LOST,
206 0,
207 0,
208 0,
209 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER},
210 {OID_802_3_XMIT_LATE_COLLISIONS,
211 0,
212 0,
213 0,
214 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL},
215#ifdef SK_POWER_MGMT
216 {OID_PNP_CAPABILITIES,
217 0,
218 0,
219 0,
220 SK_PNMI_RO, PowerManagement, 0},
221 {OID_PNP_SET_POWER,
222 0,
223 0,
224 0,
225 SK_PNMI_WO, PowerManagement, 0},
226 {OID_PNP_QUERY_POWER,
227 0,
228 0,
229 0,
230 SK_PNMI_RO, PowerManagement, 0},
231 {OID_PNP_ADD_WAKE_UP_PATTERN,
232 0,
233 0,
234 0,
235 SK_PNMI_WO, PowerManagement, 0},
236 {OID_PNP_REMOVE_WAKE_UP_PATTERN,
237 0,
238 0,
239 0,
240 SK_PNMI_WO, PowerManagement, 0},
241 {OID_PNP_ENABLE_WAKE_UP,
242 0,
243 0,
244 0,
245 SK_PNMI_RW, PowerManagement, 0},
246#endif /* SK_POWER_MGMT */
247#ifdef SK_DIAG_SUPPORT
248 {OID_SKGE_DIAG_MODE,
249 0,
250 0,
251 0,
252 SK_PNMI_RW, DiagActions, 0},
253#endif /* SK_DIAG_SUPPORT */
254 {OID_SKGE_MDB_VERSION,
255 1,
256 0,
257 SK_PNMI_MAI_OFF(MgmtDBVersion),
258 SK_PNMI_RO, General, 0},
259 {OID_SKGE_SUPPORTED_LIST,
260 0,
261 0,
262 0,
263 SK_PNMI_RO, General, 0},
264 {OID_SKGE_ALL_DATA,
265 0,
266 0,
267 0,
268 SK_PNMI_RW, OidStruct, 0},
269 {OID_SKGE_VPD_FREE_BYTES,
270 1,
271 0,
272 SK_PNMI_MAI_OFF(VpdFreeBytes),
273 SK_PNMI_RO, Vpd, 0},
274 {OID_SKGE_VPD_ENTRIES_LIST,
275 1,
276 0,
277 SK_PNMI_MAI_OFF(VpdEntriesList),
278 SK_PNMI_RO, Vpd, 0},
279 {OID_SKGE_VPD_ENTRIES_NUMBER,
280 1,
281 0,
282 SK_PNMI_MAI_OFF(VpdEntriesNumber),
283 SK_PNMI_RO, Vpd, 0},
284 {OID_SKGE_VPD_KEY,
285 SK_PNMI_VPD_ENTRIES,
286 sizeof(SK_PNMI_VPD),
287 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey),
288 SK_PNMI_RO, Vpd, 0},
289 {OID_SKGE_VPD_VALUE,
290 SK_PNMI_VPD_ENTRIES,
291 sizeof(SK_PNMI_VPD),
292 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue),
293 SK_PNMI_RO, Vpd, 0},
294 {OID_SKGE_VPD_ACCESS,
295 SK_PNMI_VPD_ENTRIES,
296 sizeof(SK_PNMI_VPD),
297 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess),
298 SK_PNMI_RO, Vpd, 0},
299 {OID_SKGE_VPD_ACTION,
300 SK_PNMI_VPD_ENTRIES,
301 sizeof(SK_PNMI_VPD),
302 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction),
303 SK_PNMI_RW, Vpd, 0},
304 {OID_SKGE_PORT_NUMBER,
305 1,
306 0,
307 SK_PNMI_MAI_OFF(PortNumber),
308 SK_PNMI_RO, General, 0},
309 {OID_SKGE_DEVICE_TYPE,
310 1,
311 0,
312 SK_PNMI_MAI_OFF(DeviceType),
313 SK_PNMI_RO, General, 0},
314 {OID_SKGE_DRIVER_DESCR,
315 1,
316 0,
317 SK_PNMI_MAI_OFF(DriverDescr),
318 SK_PNMI_RO, General, 0},
319 {OID_SKGE_DRIVER_VERSION,
320 1,
321 0,
322 SK_PNMI_MAI_OFF(DriverVersion),
323 SK_PNMI_RO, General, 0},
324 {OID_SKGE_DRIVER_RELDATE,
325 1,
326 0,
327 SK_PNMI_MAI_OFF(DriverReleaseDate),
328 SK_PNMI_RO, General, 0},
329 {OID_SKGE_DRIVER_FILENAME,
330 1,
331 0,
332 SK_PNMI_MAI_OFF(DriverFileName),
333 SK_PNMI_RO, General, 0},
334 {OID_SKGE_HW_DESCR,
335 1,
336 0,
337 SK_PNMI_MAI_OFF(HwDescr),
338 SK_PNMI_RO, General, 0},
339 {OID_SKGE_HW_VERSION,
340 1,
341 0,
342 SK_PNMI_MAI_OFF(HwVersion),
343 SK_PNMI_RO, General, 0},
344 {OID_SKGE_CHIPSET,
345 1,
346 0,
347 SK_PNMI_MAI_OFF(Chipset),
348 SK_PNMI_RO, General, 0},
349 {OID_SKGE_CHIPID,
350 1,
351 0,
352 SK_PNMI_MAI_OFF(ChipId),
353 SK_PNMI_RO, General, 0},
354 {OID_SKGE_RAMSIZE,
355 1,
356 0,
357 SK_PNMI_MAI_OFF(RamSize),
358 SK_PNMI_RO, General, 0},
359 {OID_SKGE_VAUXAVAIL,
360 1,
361 0,
362 SK_PNMI_MAI_OFF(VauxAvail),
363 SK_PNMI_RO, General, 0},
364 {OID_SKGE_ACTION,
365 1,
366 0,
367 SK_PNMI_MAI_OFF(Action),
368 SK_PNMI_RW, Perform, 0},
369 {OID_SKGE_RESULT,
370 1,
371 0,
372 SK_PNMI_MAI_OFF(TestResult),
373 SK_PNMI_RO, General, 0},
374 {OID_SKGE_BUS_TYPE,
375 1,
376 0,
377 SK_PNMI_MAI_OFF(BusType),
378 SK_PNMI_RO, General, 0},
379 {OID_SKGE_BUS_SPEED,
380 1,
381 0,
382 SK_PNMI_MAI_OFF(BusSpeed),
383 SK_PNMI_RO, General, 0},
384 {OID_SKGE_BUS_WIDTH,
385 1,
386 0,
387 SK_PNMI_MAI_OFF(BusWidth),
388 SK_PNMI_RO, General, 0},
389 {OID_SKGE_TX_SW_QUEUE_LEN,
390 1,
391 0,
392 SK_PNMI_MAI_OFF(TxSwQueueLen),
393 SK_PNMI_RO, General, 0},
394 {OID_SKGE_TX_SW_QUEUE_MAX,
395 1,
396 0,
397 SK_PNMI_MAI_OFF(TxSwQueueMax),
398 SK_PNMI_RO, General, 0},
399 {OID_SKGE_TX_RETRY,
400 1,
401 0,
402 SK_PNMI_MAI_OFF(TxRetryCts),
403 SK_PNMI_RO, General, 0},
404 {OID_SKGE_RX_INTR_CTS,
405 1,
406 0,
407 SK_PNMI_MAI_OFF(RxIntrCts),
408 SK_PNMI_RO, General, 0},
409 {OID_SKGE_TX_INTR_CTS,
410 1,
411 0,
412 SK_PNMI_MAI_OFF(TxIntrCts),
413 SK_PNMI_RO, General, 0},
414 {OID_SKGE_RX_NO_BUF_CTS,
415 1,
416 0,
417 SK_PNMI_MAI_OFF(RxNoBufCts),
418 SK_PNMI_RO, General, 0},
419 {OID_SKGE_TX_NO_BUF_CTS,
420 1,
421 0,
422 SK_PNMI_MAI_OFF(TxNoBufCts),
423 SK_PNMI_RO, General, 0},
424 {OID_SKGE_TX_USED_DESCR_NO,
425 1,
426 0,
427 SK_PNMI_MAI_OFF(TxUsedDescrNo),
428 SK_PNMI_RO, General, 0},
429 {OID_SKGE_RX_DELIVERED_CTS,
430 1,
431 0,
432 SK_PNMI_MAI_OFF(RxDeliveredCts),
433 SK_PNMI_RO, General, 0},
434 {OID_SKGE_RX_OCTETS_DELIV_CTS,
435 1,
436 0,
437 SK_PNMI_MAI_OFF(RxOctetsDeliveredCts),
438 SK_PNMI_RO, General, 0},
439 {OID_SKGE_RX_HW_ERROR_CTS,
440 1,
441 0,
442 SK_PNMI_MAI_OFF(RxHwErrorsCts),
443 SK_PNMI_RO, General, 0},
444 {OID_SKGE_TX_HW_ERROR_CTS,
445 1,
446 0,
447 SK_PNMI_MAI_OFF(TxHwErrorsCts),
448 SK_PNMI_RO, General, 0},
449 {OID_SKGE_IN_ERRORS_CTS,
450 1,
451 0,
452 SK_PNMI_MAI_OFF(InErrorsCts),
453 SK_PNMI_RO, General, 0},
454 {OID_SKGE_OUT_ERROR_CTS,
455 1,
456 0,
457 SK_PNMI_MAI_OFF(OutErrorsCts),
458 SK_PNMI_RO, General, 0},
459 {OID_SKGE_ERR_RECOVERY_CTS,
460 1,
461 0,
462 SK_PNMI_MAI_OFF(ErrRecoveryCts),
463 SK_PNMI_RO, General, 0},
464 {OID_SKGE_SYSUPTIME,
465 1,
466 0,
467 SK_PNMI_MAI_OFF(SysUpTime),
468 SK_PNMI_RO, General, 0},
469 {OID_SKGE_SENSOR_NUMBER,
470 1,
471 0,
472 SK_PNMI_MAI_OFF(SensorNumber),
473 SK_PNMI_RO, General, 0},
474 {OID_SKGE_SENSOR_INDEX,
475 SK_PNMI_SENSOR_ENTRIES,
476 sizeof(SK_PNMI_SENSOR),
477 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex),
478 SK_PNMI_RO, SensorStat, 0},
479 {OID_SKGE_SENSOR_DESCR,
480 SK_PNMI_SENSOR_ENTRIES,
481 sizeof(SK_PNMI_SENSOR),
482 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr),
483 SK_PNMI_RO, SensorStat, 0},
484 {OID_SKGE_SENSOR_TYPE,
485 SK_PNMI_SENSOR_ENTRIES,
486 sizeof(SK_PNMI_SENSOR),
487 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType),
488 SK_PNMI_RO, SensorStat, 0},
489 {OID_SKGE_SENSOR_VALUE,
490 SK_PNMI_SENSOR_ENTRIES,
491 sizeof(SK_PNMI_SENSOR),
492 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue),
493 SK_PNMI_RO, SensorStat, 0},
494 {OID_SKGE_SENSOR_WAR_THRES_LOW,
495 SK_PNMI_SENSOR_ENTRIES,
496 sizeof(SK_PNMI_SENSOR),
497 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow),
498 SK_PNMI_RO, SensorStat, 0},
499 {OID_SKGE_SENSOR_WAR_THRES_UPP,
500 SK_PNMI_SENSOR_ENTRIES,
501 sizeof(SK_PNMI_SENSOR),
502 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh),
503 SK_PNMI_RO, SensorStat, 0},
504 {OID_SKGE_SENSOR_ERR_THRES_LOW,
505 SK_PNMI_SENSOR_ENTRIES,
506 sizeof(SK_PNMI_SENSOR),
507 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow),
508 SK_PNMI_RO, SensorStat, 0},
509 {OID_SKGE_SENSOR_ERR_THRES_UPP,
510 SK_PNMI_SENSOR_ENTRIES,
511 sizeof(SK_PNMI_SENSOR),
512 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh),
513 SK_PNMI_RO, SensorStat, 0},
514 {OID_SKGE_SENSOR_STATUS,
515 SK_PNMI_SENSOR_ENTRIES,
516 sizeof(SK_PNMI_SENSOR),
517 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus),
518 SK_PNMI_RO, SensorStat, 0},
519 {OID_SKGE_SENSOR_WAR_CTS,
520 SK_PNMI_SENSOR_ENTRIES,
521 sizeof(SK_PNMI_SENSOR),
522 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts),
523 SK_PNMI_RO, SensorStat, 0},
524 {OID_SKGE_SENSOR_ERR_CTS,
525 SK_PNMI_SENSOR_ENTRIES,
526 sizeof(SK_PNMI_SENSOR),
527 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts),
528 SK_PNMI_RO, SensorStat, 0},
529 {OID_SKGE_SENSOR_WAR_TIME,
530 SK_PNMI_SENSOR_ENTRIES,
531 sizeof(SK_PNMI_SENSOR),
532 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp),
533 SK_PNMI_RO, SensorStat, 0},
534 {OID_SKGE_SENSOR_ERR_TIME,
535 SK_PNMI_SENSOR_ENTRIES,
536 sizeof(SK_PNMI_SENSOR),
537 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp),
538 SK_PNMI_RO, SensorStat, 0},
539 {OID_SKGE_CHKSM_NUMBER,
540 1,
541 0,
542 SK_PNMI_MAI_OFF(ChecksumNumber),
543 SK_PNMI_RO, General, 0},
544 {OID_SKGE_CHKSM_RX_OK_CTS,
545 SKCS_NUM_PROTOCOLS,
546 sizeof(SK_PNMI_CHECKSUM),
547 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts),
548 SK_PNMI_RO, CsumStat, 0},
549 {OID_SKGE_CHKSM_RX_UNABLE_CTS,
550 SKCS_NUM_PROTOCOLS,
551 sizeof(SK_PNMI_CHECKSUM),
552 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts),
553 SK_PNMI_RO, CsumStat, 0},
554 {OID_SKGE_CHKSM_RX_ERR_CTS,
555 SKCS_NUM_PROTOCOLS,
556 sizeof(SK_PNMI_CHECKSUM),
557 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts),
558 SK_PNMI_RO, CsumStat, 0},
559 {OID_SKGE_CHKSM_TX_OK_CTS,
560 SKCS_NUM_PROTOCOLS,
561 sizeof(SK_PNMI_CHECKSUM),
562 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts),
563 SK_PNMI_RO, CsumStat, 0},
564 {OID_SKGE_CHKSM_TX_UNABLE_CTS,
565 SKCS_NUM_PROTOCOLS,
566 sizeof(SK_PNMI_CHECKSUM),
567 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts),
568 SK_PNMI_RO, CsumStat, 0},
569 {OID_SKGE_STAT_TX,
570 SK_PNMI_MAC_ENTRIES,
571 sizeof(SK_PNMI_STAT),
572 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts),
573 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX},
574 {OID_SKGE_STAT_TX_OCTETS,
575 SK_PNMI_MAC_ENTRIES,
576 sizeof(SK_PNMI_STAT),
577 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts),
578 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET},
579 {OID_SKGE_STAT_TX_BROADCAST,
580 SK_PNMI_MAC_ENTRIES,
581 sizeof(SK_PNMI_STAT),
582 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts),
583 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST},
584 {OID_SKGE_STAT_TX_MULTICAST,
585 SK_PNMI_MAC_ENTRIES,
586 sizeof(SK_PNMI_STAT),
587 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts),
588 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST},
589 {OID_SKGE_STAT_TX_UNICAST,
590 SK_PNMI_MAC_ENTRIES,
591 sizeof(SK_PNMI_STAT),
592 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts),
593 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST},
594 {OID_SKGE_STAT_TX_LONGFRAMES,
595 SK_PNMI_MAC_ENTRIES,
596 sizeof(SK_PNMI_STAT),
597 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts),
598 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES},
599 {OID_SKGE_STAT_TX_BURST,
600 SK_PNMI_MAC_ENTRIES,
601 sizeof(SK_PNMI_STAT),
602 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts),
603 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST},
604 {OID_SKGE_STAT_TX_PFLOWC,
605 SK_PNMI_MAC_ENTRIES,
606 sizeof(SK_PNMI_STAT),
607 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts),
608 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC},
609 {OID_SKGE_STAT_TX_FLOWC,
610 SK_PNMI_MAC_ENTRIES,
611 sizeof(SK_PNMI_STAT),
612 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts),
613 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC},
614 {OID_SKGE_STAT_TX_SINGLE_COL,
615 SK_PNMI_MAC_ENTRIES,
616 sizeof(SK_PNMI_STAT),
617 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts),
618 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL},
619 {OID_SKGE_STAT_TX_MULTI_COL,
620 SK_PNMI_MAC_ENTRIES,
621 sizeof(SK_PNMI_STAT),
622 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts),
623 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL},
624 {OID_SKGE_STAT_TX_EXCESS_COL,
625 SK_PNMI_MAC_ENTRIES,
626 sizeof(SK_PNMI_STAT),
627 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts),
628 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL},
629 {OID_SKGE_STAT_TX_LATE_COL,
630 SK_PNMI_MAC_ENTRIES,
631 sizeof(SK_PNMI_STAT),
632 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts),
633 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL},
634 {OID_SKGE_STAT_TX_DEFFERAL,
635 SK_PNMI_MAC_ENTRIES,
636 sizeof(SK_PNMI_STAT),
637 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts),
638 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL},
639 {OID_SKGE_STAT_TX_EXCESS_DEF,
640 SK_PNMI_MAC_ENTRIES,
641 sizeof(SK_PNMI_STAT),
642 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts),
643 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF},
644 {OID_SKGE_STAT_TX_UNDERRUN,
645 SK_PNMI_MAC_ENTRIES,
646 sizeof(SK_PNMI_STAT),
647 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts),
648 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN},
649 {OID_SKGE_STAT_TX_CARRIER,
650 SK_PNMI_MAC_ENTRIES,
651 sizeof(SK_PNMI_STAT),
652 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts),
653 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER},
654/* {OID_SKGE_STAT_TX_UTIL,
655 SK_PNMI_MAC_ENTRIES,
656 sizeof(SK_PNMI_STAT),
657 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization),
658 SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
659 {OID_SKGE_STAT_TX_64,
660 SK_PNMI_MAC_ENTRIES,
661 sizeof(SK_PNMI_STAT),
662 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts),
663 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64},
664 {OID_SKGE_STAT_TX_127,
665 SK_PNMI_MAC_ENTRIES,
666 sizeof(SK_PNMI_STAT),
667 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts),
668 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127},
669 {OID_SKGE_STAT_TX_255,
670 SK_PNMI_MAC_ENTRIES,
671 sizeof(SK_PNMI_STAT),
672 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts),
673 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255},
674 {OID_SKGE_STAT_TX_511,
675 SK_PNMI_MAC_ENTRIES,
676 sizeof(SK_PNMI_STAT),
677 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts),
678 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511},
679 {OID_SKGE_STAT_TX_1023,
680 SK_PNMI_MAC_ENTRIES,
681 sizeof(SK_PNMI_STAT),
682 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts),
683 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023},
684 {OID_SKGE_STAT_TX_MAX,
685 SK_PNMI_MAC_ENTRIES,
686 sizeof(SK_PNMI_STAT),
687 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts),
688 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX},
689 {OID_SKGE_STAT_TX_SYNC,
690 SK_PNMI_MAC_ENTRIES,
691 sizeof(SK_PNMI_STAT),
692 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts),
693 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC},
694 {OID_SKGE_STAT_TX_SYNC_OCTETS,
695 SK_PNMI_MAC_ENTRIES,
696 sizeof(SK_PNMI_STAT),
697 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts),
698 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET},
699 {OID_SKGE_STAT_RX,
700 SK_PNMI_MAC_ENTRIES,
701 sizeof(SK_PNMI_STAT),
702 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts),
703 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX},
704 {OID_SKGE_STAT_RX_OCTETS,
705 SK_PNMI_MAC_ENTRIES,
706 sizeof(SK_PNMI_STAT),
707 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts),
708 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET},
709 {OID_SKGE_STAT_RX_BROADCAST,
710 SK_PNMI_MAC_ENTRIES,
711 sizeof(SK_PNMI_STAT),
712 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts),
713 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST},
714 {OID_SKGE_STAT_RX_MULTICAST,
715 SK_PNMI_MAC_ENTRIES,
716 sizeof(SK_PNMI_STAT),
717 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts),
718 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST},
719 {OID_SKGE_STAT_RX_UNICAST,
720 SK_PNMI_MAC_ENTRIES,
721 sizeof(SK_PNMI_STAT),
722 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
723 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
724 {OID_SKGE_STAT_RX_LONGFRAMES,
725 SK_PNMI_MAC_ENTRIES,
726 sizeof(SK_PNMI_STAT),
727 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
728 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
729 {OID_SKGE_STAT_RX_PFLOWC,
730 SK_PNMI_MAC_ENTRIES,
731 sizeof(SK_PNMI_STAT),
732 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts),
733 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC},
734 {OID_SKGE_STAT_RX_FLOWC,
735 SK_PNMI_MAC_ENTRIES,
736 sizeof(SK_PNMI_STAT),
737 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts),
738 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC},
739 {OID_SKGE_STAT_RX_PFLOWC_ERR,
740 SK_PNMI_MAC_ENTRIES,
741 sizeof(SK_PNMI_STAT),
742 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts),
743 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR},
744 {OID_SKGE_STAT_RX_FLOWC_UNKWN,
745 SK_PNMI_MAC_ENTRIES,
746 sizeof(SK_PNMI_STAT),
747 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts),
748 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN},
749 {OID_SKGE_STAT_RX_BURST,
750 SK_PNMI_MAC_ENTRIES,
751 sizeof(SK_PNMI_STAT),
752 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts),
753 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST},
754 {OID_SKGE_STAT_RX_MISSED,
755 SK_PNMI_MAC_ENTRIES,
756 sizeof(SK_PNMI_STAT),
757 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts),
758 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED},
759 {OID_SKGE_STAT_RX_FRAMING,
760 SK_PNMI_MAC_ENTRIES,
761 sizeof(SK_PNMI_STAT),
762 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts),
763 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING},
764 {OID_SKGE_STAT_RX_OVERFLOW,
765 SK_PNMI_MAC_ENTRIES,
766 sizeof(SK_PNMI_STAT),
767 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts),
768 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW},
769 {OID_SKGE_STAT_RX_JABBER,
770 SK_PNMI_MAC_ENTRIES,
771 sizeof(SK_PNMI_STAT),
772 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts),
773 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER},
774 {OID_SKGE_STAT_RX_CARRIER,
775 SK_PNMI_MAC_ENTRIES,
776 sizeof(SK_PNMI_STAT),
777 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts),
778 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER},
779 {OID_SKGE_STAT_RX_IR_LENGTH,
780 SK_PNMI_MAC_ENTRIES,
781 sizeof(SK_PNMI_STAT),
782 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts),
783 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH},
784 {OID_SKGE_STAT_RX_SYMBOL,
785 SK_PNMI_MAC_ENTRIES,
786 sizeof(SK_PNMI_STAT),
787 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts),
788 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL},
789 {OID_SKGE_STAT_RX_SHORTS,
790 SK_PNMI_MAC_ENTRIES,
791 sizeof(SK_PNMI_STAT),
792 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts),
793 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS},
794 {OID_SKGE_STAT_RX_RUNT,
795 SK_PNMI_MAC_ENTRIES,
796 sizeof(SK_PNMI_STAT),
797 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts),
798 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT},
799 {OID_SKGE_STAT_RX_CEXT,
800 SK_PNMI_MAC_ENTRIES,
801 sizeof(SK_PNMI_STAT),
802 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts),
803 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT},
804 {OID_SKGE_STAT_RX_TOO_LONG,
805 SK_PNMI_MAC_ENTRIES,
806 sizeof(SK_PNMI_STAT),
807 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts),
808 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG},
809 {OID_SKGE_STAT_RX_FCS,
810 SK_PNMI_MAC_ENTRIES,
811 sizeof(SK_PNMI_STAT),
812 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts),
813 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS},
814/* {OID_SKGE_STAT_RX_UTIL,
815 SK_PNMI_MAC_ENTRIES,
816 sizeof(SK_PNMI_STAT),
817 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization),
818 SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
819 {OID_SKGE_STAT_RX_64,
820 SK_PNMI_MAC_ENTRIES,
821 sizeof(SK_PNMI_STAT),
822 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts),
823 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64},
824 {OID_SKGE_STAT_RX_127,
825 SK_PNMI_MAC_ENTRIES,
826 sizeof(SK_PNMI_STAT),
827 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts),
828 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127},
829 {OID_SKGE_STAT_RX_255,
830 SK_PNMI_MAC_ENTRIES,
831 sizeof(SK_PNMI_STAT),
832 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts),
833 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255},
834 {OID_SKGE_STAT_RX_511,
835 SK_PNMI_MAC_ENTRIES,
836 sizeof(SK_PNMI_STAT),
837 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts),
838 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511},
839 {OID_SKGE_STAT_RX_1023,
840 SK_PNMI_MAC_ENTRIES,
841 sizeof(SK_PNMI_STAT),
842 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts),
843 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023},
844 {OID_SKGE_STAT_RX_MAX,
845 SK_PNMI_MAC_ENTRIES,
846 sizeof(SK_PNMI_STAT),
847 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts),
848 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX},
849 {OID_SKGE_PHYS_CUR_ADDR,
850 SK_PNMI_MAC_ENTRIES,
851 sizeof(SK_PNMI_CONF),
852 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr),
853 SK_PNMI_RW, Addr, 0},
854 {OID_SKGE_PHYS_FAC_ADDR,
855 SK_PNMI_MAC_ENTRIES,
856 sizeof(SK_PNMI_CONF),
857 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr),
858 SK_PNMI_RO, Addr, 0},
859 {OID_SKGE_PMD,
860 SK_PNMI_MAC_ENTRIES,
861 sizeof(SK_PNMI_CONF),
862 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD),
863 SK_PNMI_RO, MacPrivateConf, 0},
864 {OID_SKGE_CONNECTOR,
865 SK_PNMI_MAC_ENTRIES,
866 sizeof(SK_PNMI_CONF),
867 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
868 SK_PNMI_RO, MacPrivateConf, 0},
869 {OID_SKGE_PHY_TYPE,
870 SK_PNMI_MAC_ENTRIES,
871 sizeof(SK_PNMI_CONF),
872 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType),
873 SK_PNMI_RO, MacPrivateConf, 0},
874 {OID_SKGE_LINK_CAP,
875 SK_PNMI_MAC_ENTRIES,
876 sizeof(SK_PNMI_CONF),
877 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability),
878 SK_PNMI_RO, MacPrivateConf, 0},
879 {OID_SKGE_LINK_MODE,
880 SK_PNMI_MAC_ENTRIES,
881 sizeof(SK_PNMI_CONF),
882 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode),
883 SK_PNMI_RW, MacPrivateConf, 0},
884 {OID_SKGE_LINK_MODE_STATUS,
885 SK_PNMI_MAC_ENTRIES,
886 sizeof(SK_PNMI_CONF),
887 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus),
888 SK_PNMI_RO, MacPrivateConf, 0},
889 {OID_SKGE_LINK_STATUS,
890 SK_PNMI_MAC_ENTRIES,
891 sizeof(SK_PNMI_CONF),
892 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus),
893 SK_PNMI_RO, MacPrivateConf, 0},
894 {OID_SKGE_FLOWCTRL_CAP,
895 SK_PNMI_MAC_ENTRIES,
896 sizeof(SK_PNMI_CONF),
897 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability),
898 SK_PNMI_RO, MacPrivateConf, 0},
899 {OID_SKGE_FLOWCTRL_MODE,
900 SK_PNMI_MAC_ENTRIES,
901 sizeof(SK_PNMI_CONF),
902 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode),
903 SK_PNMI_RW, MacPrivateConf, 0},
904 {OID_SKGE_FLOWCTRL_STATUS,
905 SK_PNMI_MAC_ENTRIES,
906 sizeof(SK_PNMI_CONF),
907 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus),
908 SK_PNMI_RO, MacPrivateConf, 0},
909 {OID_SKGE_PHY_OPERATION_CAP,
910 SK_PNMI_MAC_ENTRIES,
911 sizeof(SK_PNMI_CONF),
912 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability),
913 SK_PNMI_RO, MacPrivateConf, 0},
914 {OID_SKGE_PHY_OPERATION_MODE,
915 SK_PNMI_MAC_ENTRIES,
916 sizeof(SK_PNMI_CONF),
917 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode),
918 SK_PNMI_RW, MacPrivateConf, 0},
919 {OID_SKGE_PHY_OPERATION_STATUS,
920 SK_PNMI_MAC_ENTRIES,
921 sizeof(SK_PNMI_CONF),
922 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus),
923 SK_PNMI_RO, MacPrivateConf, 0},
924 {OID_SKGE_SPEED_CAP,
925 SK_PNMI_MAC_ENTRIES,
926 sizeof(SK_PNMI_CONF),
927 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability),
928 SK_PNMI_RO, MacPrivateConf, 0},
929 {OID_SKGE_SPEED_MODE,
930 SK_PNMI_MAC_ENTRIES,
931 sizeof(SK_PNMI_CONF),
932 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode),
933 SK_PNMI_RW, MacPrivateConf, 0},
934 {OID_SKGE_SPEED_STATUS,
935 SK_PNMI_MAC_ENTRIES,
936 sizeof(SK_PNMI_CONF),
937 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus),
938 SK_PNMI_RO, MacPrivateConf, 0},
939 {OID_SKGE_TRAP,
940 1,
941 0,
942 SK_PNMI_MAI_OFF(Trap),
943 SK_PNMI_RO, General, 0},
944 {OID_SKGE_TRAP_NUMBER,
945 1,
946 0,
947 SK_PNMI_MAI_OFF(TrapNumber),
948 SK_PNMI_RO, General, 0},
949 {OID_SKGE_RLMT_MODE,
950 1,
951 0,
952 SK_PNMI_MAI_OFF(RlmtMode),
953 SK_PNMI_RW, Rlmt, 0},
954 {OID_SKGE_RLMT_PORT_NUMBER,
955 1,
956 0,
957 SK_PNMI_MAI_OFF(RlmtPortNumber),
958 SK_PNMI_RO, Rlmt, 0},
959 {OID_SKGE_RLMT_PORT_ACTIVE,
960 1,
961 0,
962 SK_PNMI_MAI_OFF(RlmtPortActive),
963 SK_PNMI_RO, Rlmt, 0},
964 {OID_SKGE_RLMT_PORT_PREFERRED,
965 1,
966 0,
967 SK_PNMI_MAI_OFF(RlmtPortPreferred),
968 SK_PNMI_RW, Rlmt, 0},
969 {OID_SKGE_RLMT_CHANGE_CTS,
970 1,
971 0,
972 SK_PNMI_MAI_OFF(RlmtChangeCts),
973 SK_PNMI_RO, Rlmt, 0},
974 {OID_SKGE_RLMT_CHANGE_TIME,
975 1,
976 0,
977 SK_PNMI_MAI_OFF(RlmtChangeTime),
978 SK_PNMI_RO, Rlmt, 0},
979 {OID_SKGE_RLMT_CHANGE_ESTIM,
980 1,
981 0,
982 SK_PNMI_MAI_OFF(RlmtChangeEstimate),
983 SK_PNMI_RO, Rlmt, 0},
984 {OID_SKGE_RLMT_CHANGE_THRES,
985 1,
986 0,
987 SK_PNMI_MAI_OFF(RlmtChangeThreshold),
988 SK_PNMI_RW, Rlmt, 0},
989 {OID_SKGE_RLMT_PORT_INDEX,
990 SK_PNMI_MAC_ENTRIES,
991 sizeof(SK_PNMI_RLMT),
992 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex),
993 SK_PNMI_RO, RlmtStat, 0},
994 {OID_SKGE_RLMT_STATUS,
995 SK_PNMI_MAC_ENTRIES,
996 sizeof(SK_PNMI_RLMT),
997 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus),
998 SK_PNMI_RO, RlmtStat, 0},
999 {OID_SKGE_RLMT_TX_HELLO_CTS,
1000 SK_PNMI_MAC_ENTRIES,
1001 sizeof(SK_PNMI_RLMT),
1002 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts),
1003 SK_PNMI_RO, RlmtStat, 0},
1004 {OID_SKGE_RLMT_RX_HELLO_CTS,
1005 SK_PNMI_MAC_ENTRIES,
1006 sizeof(SK_PNMI_RLMT),
1007 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts),
1008 SK_PNMI_RO, RlmtStat, 0},
1009 {OID_SKGE_RLMT_TX_SP_REQ_CTS,
1010 SK_PNMI_MAC_ENTRIES,
1011 sizeof(SK_PNMI_RLMT),
1012 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts),
1013 SK_PNMI_RO, RlmtStat, 0},
1014 {OID_SKGE_RLMT_RX_SP_CTS,
1015 SK_PNMI_MAC_ENTRIES,
1016 sizeof(SK_PNMI_RLMT),
1017 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts),
1018 SK_PNMI_RO, RlmtStat, 0},
1019 {OID_SKGE_RLMT_MONITOR_NUMBER,
1020 1,
1021 0,
1022 SK_PNMI_MAI_OFF(RlmtMonitorNumber),
1023 SK_PNMI_RO, General, 0},
1024 {OID_SKGE_RLMT_MONITOR_INDEX,
1025 SK_PNMI_MONITOR_ENTRIES,
1026 sizeof(SK_PNMI_RLMT_MONITOR),
1027 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex),
1028 SK_PNMI_RO, Monitor, 0},
1029 {OID_SKGE_RLMT_MONITOR_ADDR,
1030 SK_PNMI_MONITOR_ENTRIES,
1031 sizeof(SK_PNMI_RLMT_MONITOR),
1032 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr),
1033 SK_PNMI_RO, Monitor, 0},
1034 {OID_SKGE_RLMT_MONITOR_ERRS,
1035 SK_PNMI_MONITOR_ENTRIES,
1036 sizeof(SK_PNMI_RLMT_MONITOR),
1037 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts),
1038 SK_PNMI_RO, Monitor, 0},
1039 {OID_SKGE_RLMT_MONITOR_TIMESTAMP,
1040 SK_PNMI_MONITOR_ENTRIES,
1041 sizeof(SK_PNMI_RLMT_MONITOR),
1042 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp),
1043 SK_PNMI_RO, Monitor, 0},
1044 {OID_SKGE_RLMT_MONITOR_ADMIN,
1045 SK_PNMI_MONITOR_ENTRIES,
1046 sizeof(SK_PNMI_RLMT_MONITOR),
1047 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
1048 SK_PNMI_RW, Monitor, 0},
1049 {OID_SKGE_MTU,
1050 1,
1051 0,
1052 SK_PNMI_MAI_OFF(MtuSize),
1053 SK_PNMI_RW, MacPrivateConf, 0},
1054 {OID_SKGE_VCT_GET,
1055 0,
1056 0,
1057 0,
1058 SK_PNMI_RO, Vct, 0},
1059 {OID_SKGE_VCT_SET,
1060 0,
1061 0,
1062 0,
1063 SK_PNMI_WO, Vct, 0},
1064 {OID_SKGE_VCT_STATUS,
1065 0,
1066 0,
1067 0,
1068 SK_PNMI_RO, Vct, 0},
1069 {OID_SKGE_BOARDLEVEL,
1070 0,
1071 0,
1072 0,
1073 SK_PNMI_RO, General, 0},
1074};
1075
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
deleted file mode 100644
index 876bb2158fa6..000000000000
--- a/drivers/net/sk98lin/skgepnmi.c
+++ /dev/null
@@ -1,8198 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgepnmi.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.111 $
6 * Date: $Date: 2003/09/15 13:35:35 $
7 * Purpose: Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26#ifndef _lint
27static const char SysKonnectFileId[] =
28 "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
29#endif /* !_lint */
30
31#include "h/skdrv1st.h"
32#include "h/sktypes.h"
33#include "h/xmac_ii.h"
34#include "h/skdebug.h"
35#include "h/skqueue.h"
36#include "h/skgepnmi.h"
37#include "h/skgesirq.h"
38#include "h/skcsum.h"
39#include "h/skvpd.h"
40#include "h/skgehw.h"
41#include "h/skgeinit.h"
42#include "h/skdrv2nd.h"
43#include "h/skgepnm2.h"
44#ifdef SK_POWER_MGMT
45#include "h/skgepmgt.h"
46#endif
47/* defines *******************************************************************/
48
49#ifndef DEBUG
50#define PNMI_STATIC static
51#else /* DEBUG */
52#define PNMI_STATIC
53#endif /* DEBUG */
54
55/*
56 * Public Function prototypes
57 */
58int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
59int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
62 unsigned int *pLen, SK_U32 NetIndex);
63int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
64 unsigned int *pLen, SK_U32 NetIndex);
65int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66 unsigned int *pLen, SK_U32 NetIndex);
67int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
68int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
69 unsigned int * pLen, SK_U32 NetIndex);
70
71
72/*
73 * Private Function prototypes
74 */
75
76PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
77 PhysPortIndex);
78PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
79 PhysPortIndex);
80PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
81PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
82PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
83 unsigned int PhysPortIndex, unsigned int StatIndex);
84PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
85 unsigned int StatIndex, SK_U32 NetIndex);
86PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
87PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
88 unsigned int *pEntries);
89PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
90 unsigned int KeyArrLen, unsigned int *pKeyNo);
91PNMI_STATIC int LookupId(SK_U32 Id);
92PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
93 unsigned int LastMac);
94PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
95 unsigned int *pLen, SK_U32 NetIndex);
96PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
97 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
98PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
99PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
100 unsigned int PortIndex);
101PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
102 unsigned int SensorIndex);
103PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
104PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
105PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
106PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
107PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
108PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
109 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
110PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
111
112/*
113 * Table to correlate OID with handler function and index to
114 * hardware register stored in StatAddress if applicable.
115 */
116#include "skgemib.c"
117
118/* global variables **********************************************************/
119
120/*
121 * Overflow status register bit table and corresponding counter
122 * dependent on MAC type - the number relates to the size of overflow
123 * mask returned by the pFnMacOverflow function
124 */
125PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
126/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
127/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
128/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
129/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
130/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
131/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
132/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
133/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
134/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
135/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
136/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
137/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
138/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
139/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
140/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
141/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
142/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
143/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
144/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
145/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
146/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
147/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
148/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
149/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
150/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
151/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
152/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
153/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
154/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
155/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
156/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
159/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
160/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
161/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
162/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
163/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
164/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
165/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
166/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
167/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
168/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
169/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
170/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
171/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
172/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
173/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
174/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
175/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
176/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
177/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
178/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
179/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
180/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
181/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
182/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
183/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
184/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
185/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
186/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
187/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
188/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
189/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
190};
191
192/*
193 * Table for hardware register saving on resets and port switches
194 */
195PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
196 /* SK_PNMI_HTX */
197 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
198 /* SK_PNMI_HTX_OCTETHIGH */
199 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
200 /* SK_PNMI_HTX_OCTETLOW */
201 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
202 /* SK_PNMI_HTX_BROADCAST */
203 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
204 /* SK_PNMI_HTX_MULTICAST */
205 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
206 /* SK_PNMI_HTX_UNICAST */
207 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
208 /* SK_PNMI_HTX_BURST */
209 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
210 /* SK_PNMI_HTX_PMACC */
211 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
212 /* SK_PNMI_HTX_MACC */
213 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
214 /* SK_PNMI_HTX_COL */
215 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
216 /* SK_PNMI_HTX_SINGLE_COL */
217 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
218 /* SK_PNMI_HTX_MULTI_COL */
219 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
220 /* SK_PNMI_HTX_EXCESS_COL */
221 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
222 /* SK_PNMI_HTX_LATE_COL */
223 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
224 /* SK_PNMI_HTX_DEFFERAL */
225 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
226 /* SK_PNMI_HTX_EXCESS_DEF */
227 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
228 /* SK_PNMI_HTX_UNDERRUN */
229 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
230 /* SK_PNMI_HTX_CARRIER */
231 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
232 /* SK_PNMI_HTX_UTILUNDER */
233 {{0, SK_FALSE}, {0, SK_FALSE}},
234 /* SK_PNMI_HTX_UTILOVER */
235 {{0, SK_FALSE}, {0, SK_FALSE}},
236 /* SK_PNMI_HTX_64 */
237 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
238 /* SK_PNMI_HTX_127 */
239 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
240 /* SK_PNMI_HTX_255 */
241 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
242 /* SK_PNMI_HTX_511 */
243 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
244 /* SK_PNMI_HTX_1023 */
245 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
246 /* SK_PNMI_HTX_MAX */
247 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
248 /* SK_PNMI_HTX_LONGFRAMES */
249 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
250 /* SK_PNMI_HTX_SYNC */
251 {{0, SK_FALSE}, {0, SK_FALSE}},
252 /* SK_PNMI_HTX_SYNC_OCTET */
253 {{0, SK_FALSE}, {0, SK_FALSE}},
254 /* SK_PNMI_HTX_RESERVED */
255 {{0, SK_FALSE}, {0, SK_FALSE}},
256 /* SK_PNMI_HRX */
257 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
258 /* SK_PNMI_HRX_OCTETHIGH */
259 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
260 /* SK_PNMI_HRX_OCTETLOW */
261 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
262 /* SK_PNMI_HRX_BADOCTETHIGH */
263 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
264 /* SK_PNMI_HRX_BADOCTETLOW */
265 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
266 /* SK_PNMI_HRX_BROADCAST */
267 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
268 /* SK_PNMI_HRX_MULTICAST */
269 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
270 /* SK_PNMI_HRX_UNICAST */
271 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
272 /* SK_PNMI_HRX_PMACC */
273 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
274 /* SK_PNMI_HRX_MACC */
275 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
276 /* SK_PNMI_HRX_PMACC_ERR */
277 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
278 /* SK_PNMI_HRX_MACC_UNKWN */
279 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
280 /* SK_PNMI_HRX_BURST */
281 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
282 /* SK_PNMI_HRX_MISSED */
283 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
284 /* SK_PNMI_HRX_FRAMING */
285 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
286 /* SK_PNMI_HRX_UNDERSIZE */
287 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
288 /* SK_PNMI_HRX_OVERFLOW */
289 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
290 /* SK_PNMI_HRX_JABBER */
291 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
292 /* SK_PNMI_HRX_CARRIER */
293 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
294 /* SK_PNMI_HRX_IRLENGTH */
295 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
296 /* SK_PNMI_HRX_SYMBOL */
297 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
298 /* SK_PNMI_HRX_SHORTS */
299 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
300 /* SK_PNMI_HRX_RUNT */
301 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
302 /* SK_PNMI_HRX_TOO_LONG */
303 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
304 /* SK_PNMI_HRX_FCS */
305 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
306 /* SK_PNMI_HRX_CEXT */
307 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
308 /* SK_PNMI_HRX_UTILUNDER */
309 {{0, SK_FALSE}, {0, SK_FALSE}},
310 /* SK_PNMI_HRX_UTILOVER */
311 {{0, SK_FALSE}, {0, SK_FALSE}},
312 /* SK_PNMI_HRX_64 */
313 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
314 /* SK_PNMI_HRX_127 */
315 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
316 /* SK_PNMI_HRX_255 */
317 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
318 /* SK_PNMI_HRX_511 */
319 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
320 /* SK_PNMI_HRX_1023 */
321 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
322 /* SK_PNMI_HRX_MAX */
323 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
324 /* SK_PNMI_HRX_LONGFRAMES */
325 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
326 /* SK_PNMI_HRX_RESERVED */
327 {{0, SK_FALSE}, {0, SK_FALSE}}
328};
329
330
331/*****************************************************************************
332 *
333 * Public functions
334 *
335 */
336
337/*****************************************************************************
338 *
339 * SkPnmiInit - Init function of PNMI
340 *
341 * Description:
342 * SK_INIT_DATA: Initialises the data structures
343 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
344 * connector type.
345 * SK_INIT_RUN: Starts a timer event for port switch per hour
346 * calculation.
347 *
348 * Returns:
349 * Always 0
350 */
351int SkPnmiInit(
352SK_AC *pAC, /* Pointer to adapter context */
353SK_IOC IoC, /* IO context handle */
354int Level) /* Initialization level */
355{
356 unsigned int PortMax; /* Number of ports */
357 unsigned int PortIndex; /* Current port index in loop */
358 SK_U16 Val16; /* Multiple purpose 16 bit variable */
359 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
360 SK_EVPARA EventParam; /* Event struct for timer event */
361 SK_PNMI_VCT *pVctBackupData;
362
363
364 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
365 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
366
367 switch (Level) {
368
369 case SK_INIT_DATA:
370 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
371 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
372 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
373 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
374 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
375
376 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
377 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
378 }
379
380#ifdef SK_PNMI_CHECK
381 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
382
383 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
384
385 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
386 ("CounterOffset struct size (%d) differs from "
387 "SK_PNMI_MAX_IDX (%d)\n",
388 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
389 }
390
391#endif /* SK_PNMI_CHECK */
392 break;
393
394 case SK_INIT_IO:
395 /*
396 * Reset MAC counters
397 */
398 PortMax = pAC->GIni.GIMacsFound;
399
400 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
401
402 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
403 }
404
405 /* Initialize DSP variables for Vct() to 0xff => Never written! */
406 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
407 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
408 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
409 pVctBackupData->PCableLen = 0xff;
410 }
411
412 /*
413 * Get pci bus speed
414 */
415 SK_IN16(IoC, B0_CTST, &Val16);
416 if ((Val16 & CS_BUS_CLOCK) == 0) {
417
418 pAC->Pnmi.PciBusSpeed = 33;
419 }
420 else {
421 pAC->Pnmi.PciBusSpeed = 66;
422 }
423
424 /*
425 * Get pci bus width
426 */
427 SK_IN16(IoC, B0_CTST, &Val16);
428 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
429
430 pAC->Pnmi.PciBusWidth = 32;
431 }
432 else {
433 pAC->Pnmi.PciBusWidth = 64;
434 }
435
436 /*
437 * Get chipset
438 */
439 switch (pAC->GIni.GIChipId) {
440 case CHIP_ID_GENESIS:
441 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
442 break;
443
444 case CHIP_ID_YUKON:
445 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
446 break;
447
448 default:
449 break;
450 }
451
452 /*
453 * Get PMD and DeviceType
454 */
455 SK_IN8(IoC, B2_PMD_TYP, &Val8);
456 switch (Val8) {
457 case 'S':
458 pAC->Pnmi.PMD = 3;
459 if (pAC->GIni.GIMacsFound > 1) {
460
461 pAC->Pnmi.DeviceType = 0x00020002;
462 }
463 else {
464 pAC->Pnmi.DeviceType = 0x00020001;
465 }
466 break;
467
468 case 'L':
469 pAC->Pnmi.PMD = 2;
470 if (pAC->GIni.GIMacsFound > 1) {
471
472 pAC->Pnmi.DeviceType = 0x00020004;
473 }
474 else {
475 pAC->Pnmi.DeviceType = 0x00020003;
476 }
477 break;
478
479 case 'C':
480 pAC->Pnmi.PMD = 4;
481 if (pAC->GIni.GIMacsFound > 1) {
482
483 pAC->Pnmi.DeviceType = 0x00020006;
484 }
485 else {
486 pAC->Pnmi.DeviceType = 0x00020005;
487 }
488 break;
489
490 case 'T':
491 pAC->Pnmi.PMD = 5;
492 if (pAC->GIni.GIMacsFound > 1) {
493
494 pAC->Pnmi.DeviceType = 0x00020008;
495 }
496 else {
497 pAC->Pnmi.DeviceType = 0x00020007;
498 }
499 break;
500
501 default :
502 pAC->Pnmi.PMD = 1;
503 pAC->Pnmi.DeviceType = 0;
504 break;
505 }
506
507 /*
508 * Get connector
509 */
510 SK_IN8(IoC, B2_CONN_TYP, &Val8);
511 switch (Val8) {
512 case 'C':
513 pAC->Pnmi.Connector = 2;
514 break;
515
516 case 'D':
517 pAC->Pnmi.Connector = 3;
518 break;
519
520 case 'F':
521 pAC->Pnmi.Connector = 4;
522 break;
523
524 case 'J':
525 pAC->Pnmi.Connector = 5;
526 break;
527
528 case 'V':
529 pAC->Pnmi.Connector = 6;
530 break;
531
532 default:
533 pAC->Pnmi.Connector = 1;
534 break;
535 }
536 break;
537
538 case SK_INIT_RUN:
539 /*
540 * Start timer for RLMT change counter
541 */
542 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
543 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
544 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
545 EventParam);
546 break;
547
548 default:
549 break; /* Nothing todo */
550 }
551
552 return (0);
553}
554
555/*****************************************************************************
556 *
557 * SkPnmiGetVar - Retrieves the value of a single OID
558 *
559 * Description:
560 * Calls a general sub-function for all this stuff. If the instance
561 * -1 is passed, the values of all instances are returned in an
562 * array of values.
563 *
564 * Returns:
565 * SK_PNMI_ERR_OK The request was successfully performed
566 * SK_PNMI_ERR_GENERAL A general severe internal error occured
567 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
568 * the data.
569 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
570 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
571 * exist (e.g. port instance 3 on a two port
572 * adapter.
573 */
574static int SkPnmiGetVar(
575SK_AC *pAC, /* Pointer to adapter context */
576SK_IOC IoC, /* IO context handle */
577SK_U32 Id, /* Object ID that is to be processed */
578void *pBuf, /* Buffer to which the management data will be copied */
579unsigned int *pLen, /* On call: buffer length. On return: used buffer */
580SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
581SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
582{
583 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
584 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
585 Id, *pLen, Instance, NetIndex));
586
587 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
588 Instance, NetIndex));
589}
590
591/*****************************************************************************
592 *
593 * SkPnmiPreSetVar - Presets the value of a single OID
594 *
595 * Description:
596 * Calls a general sub-function for all this stuff. The preset does
597 * the same as a set, but returns just before finally setting the
598 * new value. This is useful to check if a set might be successfull.
599 * If the instance -1 is passed, an array of values is supposed and
600 * all instances of the OID will be set.
601 *
602 * Returns:
603 * SK_PNMI_ERR_OK The request was successfully performed.
604 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
605 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
606 * the correct data (e.g. a 32bit value is
607 * needed, but a 16 bit value was passed).
608 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
609 * value range.
610 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
611 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
612 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
613 * exist (e.g. port instance 3 on a two port
614 * adapter.
615 */
616static int SkPnmiPreSetVar(
617SK_AC *pAC, /* Pointer to adapter context */
618SK_IOC IoC, /* IO context handle */
619SK_U32 Id, /* Object ID that is to be processed */
620void *pBuf, /* Buffer to which the management data will be copied */
621unsigned int *pLen, /* Total length of management data */
622SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
623SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
624{
625 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
626 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
627 Id, *pLen, Instance, NetIndex));
628
629
630 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
631 Instance, NetIndex));
632}
633
634/*****************************************************************************
635 *
636 * SkPnmiSetVar - Sets the value of a single OID
637 *
638 * Description:
639 * Calls a general sub-function for all this stuff. The preset does
640 * the same as a set, but returns just before finally setting the
641 * new value. This is useful to check if a set might be successfull.
642 * If the instance -1 is passed, an array of values is supposed and
643 * all instances of the OID will be set.
644 *
645 * Returns:
646 * SK_PNMI_ERR_OK The request was successfully performed.
647 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
648 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
649 * the correct data (e.g. a 32bit value is
650 * needed, but a 16 bit value was passed).
651 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
652 * value range.
653 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
654 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
655 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
656 * exist (e.g. port instance 3 on a two port
657 * adapter.
658 */
659int SkPnmiSetVar(
660SK_AC *pAC, /* Pointer to adapter context */
661SK_IOC IoC, /* IO context handle */
662SK_U32 Id, /* Object ID that is to be processed */
663void *pBuf, /* Buffer to which the management data will be copied */
664unsigned int *pLen, /* Total length of management data */
665SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
666SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
667{
668 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
669 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
670 Id, *pLen, Instance, NetIndex));
671
672 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
673 Instance, NetIndex));
674}
675
676/*****************************************************************************
677 *
678 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
679 *
680 * Description:
681 * Runs through the IdTable, queries the single OIDs and stores the
682 * returned data into the management database structure
683 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
684 * is stored in the IdTable. The return value of the function will also
685 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
686 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
687 *
688 * Returns:
689 * SK_PNMI_ERR_OK The request was successfully performed
690 * SK_PNMI_ERR_GENERAL A general severe internal error occured
691 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
692 * the data.
693 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
694 */
695int SkPnmiGetStruct(
696SK_AC *pAC, /* Pointer to adapter context */
697SK_IOC IoC, /* IO context handle */
698void *pBuf, /* Buffer to which the management data will be copied. */
699unsigned int *pLen, /* Length of buffer */
700SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
701{
702 int Ret;
703 unsigned int TableIndex;
704 unsigned int DstOffset;
705 unsigned int InstanceNo;
706 unsigned int InstanceCnt;
707 SK_U32 Instance;
708 unsigned int TmpLen;
709 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
710
711
712 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
713 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
714 *pLen, NetIndex));
715
716 if (*pLen < SK_PNMI_STRUCT_SIZE) {
717
718 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
719
720 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
721 (SK_U32)(-1));
722 }
723
724 *pLen = SK_PNMI_STRUCT_SIZE;
725 return (SK_PNMI_ERR_TOO_SHORT);
726 }
727
728 /*
729 * Check NetIndex
730 */
731 if (NetIndex >= pAC->Rlmt.NumNets) {
732 return (SK_PNMI_ERR_UNKNOWN_NET);
733 }
734
735 /* Update statistic */
736 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
737
738 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
739 SK_PNMI_ERR_OK) {
740
741 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
742 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
743 return (Ret);
744 }
745
746 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
747
748 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
749 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
750 return (Ret);
751 }
752
753 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
754
755 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
756 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
757 return (Ret);
758 }
759
760 /*
761 * Increment semaphores to indicate that an update was
762 * already done
763 */
764 pAC->Pnmi.MacUpdatedFlag ++;
765 pAC->Pnmi.RlmtUpdatedFlag ++;
766 pAC->Pnmi.SirqUpdatedFlag ++;
767
768 /* Get vpd keys for instance calculation */
769 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
770 if (Ret != SK_PNMI_ERR_OK) {
771
772 pAC->Pnmi.MacUpdatedFlag --;
773 pAC->Pnmi.RlmtUpdatedFlag --;
774 pAC->Pnmi.SirqUpdatedFlag --;
775
776 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
777 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
778 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
779 return (SK_PNMI_ERR_GENERAL);
780 }
781
782 /* Retrieve values */
783 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
784 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
785
786 InstanceNo = IdTable[TableIndex].InstanceNo;
787 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
788 InstanceCnt ++) {
789
790 DstOffset = IdTable[TableIndex].Offset +
791 (InstanceCnt - 1) *
792 IdTable[TableIndex].StructSize;
793
794 /*
795 * For the VPD the instance is not an index number
796 * but the key itself. Determin with the instance
797 * counter the VPD key to be used.
798 */
799 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
800 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
801 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
802 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
803
804 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
805 }
806 else {
807 Instance = (SK_U32)InstanceCnt;
808 }
809
810 TmpLen = *pLen - DstOffset;
811 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
812 IdTable[TableIndex].Id, (char *)pBuf +
813 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
814
815 /*
816 * An unknown instance error means that we reached
817 * the last instance of that variable. Proceed with
818 * the next OID in the table and ignore the return
819 * code.
820 */
821 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
822
823 break;
824 }
825
826 if (Ret != SK_PNMI_ERR_OK) {
827
828 pAC->Pnmi.MacUpdatedFlag --;
829 pAC->Pnmi.RlmtUpdatedFlag --;
830 pAC->Pnmi.SirqUpdatedFlag --;
831
832 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
833 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
834 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
835 return (Ret);
836 }
837 }
838 }
839
840 pAC->Pnmi.MacUpdatedFlag --;
841 pAC->Pnmi.RlmtUpdatedFlag --;
842 pAC->Pnmi.SirqUpdatedFlag --;
843
844 *pLen = SK_PNMI_STRUCT_SIZE;
845 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
846 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
847 return (SK_PNMI_ERR_OK);
848}
849
850/*****************************************************************************
851 *
852 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
853 *
854 * Description:
855 * Calls a general sub-function for all this set stuff. The preset does
856 * the same as a set, but returns just before finally setting the
857 * new value. This is useful to check if a set might be successfull.
858 * The sub-function runs through the IdTable, checks which OIDs are able
859 * to set, and calls the handler function of the OID to perform the
860 * preset. The return value of the function will also be stored in
861 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
862 * SK_PNMI_MIN_STRUCT_SIZE.
863 *
864 * Returns:
865 * SK_PNMI_ERR_OK The request was successfully performed.
866 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
867 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
868 * the correct data (e.g. a 32bit value is
869 * needed, but a 16 bit value was passed).
870 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
871 * value range.
872 */
873int SkPnmiPreSetStruct(
874SK_AC *pAC, /* Pointer to adapter context */
875SK_IOC IoC, /* IO context handle */
876void *pBuf, /* Buffer which contains the data to be set */
877unsigned int *pLen, /* Length of buffer */
878SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
879{
880 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
881 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
882 *pLen, NetIndex));
883
884 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
885 pLen, NetIndex));
886}
887
888/*****************************************************************************
889 *
890 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
891 *
892 * Description:
893 * Calls a general sub-function for all this set stuff. The return value
894 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
895 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
896 * The sub-function runs through the IdTable, checks which OIDs are able
897 * to set, and calls the handler function of the OID to perform the
898 * set. The return value of the function will also be stored in
899 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
900 * SK_PNMI_MIN_STRUCT_SIZE.
901 *
902 * Returns:
903 * SK_PNMI_ERR_OK The request was successfully performed.
904 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
905 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
906 * the correct data (e.g. a 32bit value is
907 * needed, but a 16 bit value was passed).
908 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
909 * value range.
910 */
911int SkPnmiSetStruct(
912SK_AC *pAC, /* Pointer to adapter context */
913SK_IOC IoC, /* IO context handle */
914void *pBuf, /* Buffer which contains the data to be set */
915unsigned int *pLen, /* Length of buffer */
916SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
917{
918 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
919 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
920 *pLen, NetIndex));
921
922 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
923 pLen, NetIndex));
924}
925
926/*****************************************************************************
927 *
928 * SkPnmiEvent - Event handler
929 *
930 * Description:
931 * Handles the following events:
932 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
933 * interrupt will be generated which is
934 * first handled by SIRQ which generates a
935 * this event. The event increments the
936 * upper 32 bit of the 64 bit counter.
937 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
938 * when a sensor reports a warning or
939 * error. The event will store a trap
940 * message in the trap buffer.
941 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
942 * module and is used to calculate the
943 * port switches per hour.
944 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
945 * timestamps.
946 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
947 * before a hard reset of the XMAC is
948 * performed. All counters will be saved
949 * and added to the hardware counter
950 * values after reset to grant continuous
951 * counter values.
952 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
953 * went logically up. A trap message will
954 * be stored to the trap buffer.
955 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
956 * went logically down. A trap message will
957 * be stored to the trap buffer.
958 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
959 * spanning tree root bridges were
960 * detected. A trap message will be stored
961 * to the trap buffer.
962 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
963 * down. PNMI will not further add the
964 * statistic values to the virtual port.
965 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
966 * is now an active port. PNMI will now
967 * add the statistic data of this port to
968 * the virtual port.
969 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
970 * contains the number of nets. 1 means single net, 2 means
971 * dual net. The second parameter is -1
972 *
973 * Returns:
974 * Always 0
975 */
976int SkPnmiEvent(
977SK_AC *pAC, /* Pointer to adapter context */
978SK_IOC IoC, /* IO context handle */
979SK_U32 Event, /* Event-Id */
980SK_EVPARA Param) /* Event dependent parameter */
981{
982 unsigned int PhysPortIndex;
983 unsigned int MaxNetNumber;
984 int CounterIndex;
985 int Ret;
986 SK_U16 MacStatus;
987 SK_U64 OverflowStatus;
988 SK_U64 Mask;
989 int MacType;
990 SK_U64 Value;
991 SK_U32 Val32;
992 SK_U16 Register;
993 SK_EVPARA EventParam;
994 SK_U64 NewestValue;
995 SK_U64 OldestValue;
996 SK_U64 Delta;
997 SK_PNMI_ESTIMATE *pEst;
998 SK_U32 NetIndex;
999 SK_GEPORT *pPrt;
1000 SK_PNMI_VCT *pVctBackupData;
1001 SK_U32 RetCode;
1002 int i;
1003 SK_U32 CableLength;
1004
1005
1006#ifdef DEBUG
1007 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1008
1009 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1010 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1011 (unsigned int)Event, (unsigned int)Param.Para64));
1012 }
1013#endif /* DEBUG */
1014 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1015
1016 MacType = pAC->GIni.GIMacType;
1017
1018 switch (Event) {
1019
1020 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1021 PhysPortIndex = (int)Param.Para32[0];
1022 MacStatus = (SK_U16)Param.Para32[1];
1023#ifdef DEBUG
1024 if (PhysPortIndex >= SK_MAX_MACS) {
1025
1026 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1027 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1028 " wrong, PhysPortIndex=0x%x\n",
1029 PhysPortIndex));
1030 return (0);
1031 }
1032#endif /* DEBUG */
1033 OverflowStatus = 0;
1034
1035 /*
1036 * Check which source caused an overflow interrupt.
1037 */
1038 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1039 MacStatus, &OverflowStatus) != 0) ||
1040 (OverflowStatus == 0)) {
1041
1042 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1043 return (0);
1044 }
1045
1046 /*
1047 * Check the overflow status register and increment
1048 * the upper dword of corresponding counter.
1049 */
1050 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1051 CounterIndex ++) {
1052
1053 Mask = (SK_U64)1 << CounterIndex;
1054 if ((OverflowStatus & Mask) == 0) {
1055
1056 continue;
1057 }
1058
1059 switch (StatOvrflwBit[CounterIndex][MacType]) {
1060
1061 case SK_PNMI_HTX_UTILUNDER:
1062 case SK_PNMI_HTX_UTILOVER:
1063 if (MacType == SK_MAC_XMAC) {
1064 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1065 Register |= XM_TX_SAM_LINE;
1066 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1067 }
1068 break;
1069
1070 case SK_PNMI_HRX_UTILUNDER:
1071 case SK_PNMI_HRX_UTILOVER:
1072 if (MacType == SK_MAC_XMAC) {
1073 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1074 Register |= XM_RX_SAM_LINE;
1075 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1076 }
1077 break;
1078
1079 case SK_PNMI_HTX_OCTETHIGH:
1080 case SK_PNMI_HTX_OCTETLOW:
1081 case SK_PNMI_HTX_RESERVED:
1082 case SK_PNMI_HRX_OCTETHIGH:
1083 case SK_PNMI_HRX_OCTETLOW:
1084 case SK_PNMI_HRX_IRLENGTH:
1085 case SK_PNMI_HRX_RESERVED:
1086
1087 /*
1088 * the following counters aren't be handled (id > 63)
1089 */
1090 case SK_PNMI_HTX_SYNC:
1091 case SK_PNMI_HTX_SYNC_OCTET:
1092 break;
1093
1094 case SK_PNMI_HRX_LONGFRAMES:
1095 if (MacType == SK_MAC_GMAC) {
1096 pAC->Pnmi.Port[PhysPortIndex].
1097 CounterHigh[CounterIndex] ++;
1098 }
1099 break;
1100
1101 default:
1102 pAC->Pnmi.Port[PhysPortIndex].
1103 CounterHigh[CounterIndex] ++;
1104 }
1105 }
1106 break;
1107
1108 case SK_PNMI_EVT_SEN_WAR_LOW:
1109#ifdef DEBUG
1110 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1111
1112 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1113 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1114 (unsigned int)Param.Para64));
1115 return (0);
1116 }
1117#endif /* DEBUG */
1118
1119 /*
1120 * Store a trap message in the trap buffer and generate
1121 * an event for user space applications with the
1122 * SK_DRIVER_SENDEVENT macro.
1123 */
1124 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1125 (unsigned int)Param.Para64);
1126 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1127 break;
1128
1129 case SK_PNMI_EVT_SEN_WAR_UPP:
1130#ifdef DEBUG
1131 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1132
1133 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1134 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1135 (unsigned int)Param.Para64));
1136 return (0);
1137 }
1138#endif /* DEBUG */
1139
1140 /*
1141 * Store a trap message in the trap buffer and generate
1142 * an event for user space applications with the
1143 * SK_DRIVER_SENDEVENT macro.
1144 */
1145 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1146 (unsigned int)Param.Para64);
1147 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1148 break;
1149
1150 case SK_PNMI_EVT_SEN_ERR_LOW:
1151#ifdef DEBUG
1152 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1153
1154 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1155 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1156 (unsigned int)Param.Para64));
1157 return (0);
1158 }
1159#endif /* DEBUG */
1160
1161 /*
1162 * Store a trap message in the trap buffer and generate
1163 * an event for user space applications with the
1164 * SK_DRIVER_SENDEVENT macro.
1165 */
1166 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1167 (unsigned int)Param.Para64);
1168 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1169 break;
1170
1171 case SK_PNMI_EVT_SEN_ERR_UPP:
1172#ifdef DEBUG
1173 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1174
1175 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1176 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1177 (unsigned int)Param.Para64));
1178 return (0);
1179 }
1180#endif /* DEBUG */
1181
1182 /*
1183 * Store a trap message in the trap buffer and generate
1184 * an event for user space applications with the
1185 * SK_DRIVER_SENDEVENT macro.
1186 */
1187 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1188 (unsigned int)Param.Para64);
1189 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1190 break;
1191
1192 case SK_PNMI_EVT_CHG_EST_TIMER:
1193 /*
1194 * Calculate port switch average on a per hour basis
1195 * Time interval for check : 28125 ms
1196 * Number of values for average : 8
1197 *
1198 * Be careful in changing these values, on change check
1199 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1200 * array one less than value number)
1201 * - Timer initialization SkTimerStart() in SkPnmiInit
1202 * - Delta value below must be multiplicated with
1203 * power of 2
1204 *
1205 */
1206 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1207 CounterIndex = pEst->EstValueIndex + 1;
1208 if (CounterIndex == 7) {
1209
1210 CounterIndex = 0;
1211 }
1212 pEst->EstValueIndex = CounterIndex;
1213
1214 NewestValue = pAC->Pnmi.RlmtChangeCts;
1215 OldestValue = pEst->EstValue[CounterIndex];
1216 pEst->EstValue[CounterIndex] = NewestValue;
1217
1218 /*
1219 * Calculate average. Delta stores the number of
1220 * port switches per 28125 * 8 = 225000 ms
1221 */
1222 if (NewestValue >= OldestValue) {
1223
1224 Delta = NewestValue - OldestValue;
1225 }
1226 else {
1227 /* Overflow situation */
1228 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1229 }
1230
1231 /*
1232 * Extrapolate delta to port switches per hour.
1233 * Estimate = Delta * (3600000 / 225000)
1234 * = Delta * 16
1235 * = Delta << 4
1236 */
1237 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1238
1239 /*
1240 * Check if threshold is exceeded. If the threshold is
1241 * permanently exceeded every 28125 ms an event will be
1242 * generated to remind the user of this condition.
1243 */
1244 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1245 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1246 pAC->Pnmi.RlmtChangeThreshold)) {
1247
1248 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1249 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1250 }
1251
1252 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1253 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1254 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1255 EventParam);
1256 break;
1257
1258 case SK_PNMI_EVT_CLEAR_COUNTER:
1259 /*
1260 * Param.Para32[0] contains the NetIndex (0 ..1).
1261 * Param.Para32[1] is reserved, contains -1.
1262 */
1263 NetIndex = (SK_U32)Param.Para32[0];
1264
1265#ifdef DEBUG
1266 if (NetIndex >= pAC->Rlmt.NumNets) {
1267
1268 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1269 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1270 NetIndex));
1271
1272 return (0);
1273 }
1274#endif /* DEBUG */
1275
1276 /*
1277 * Set all counters and timestamps to zero.
1278 * The according NetIndex is required as a
1279 * parameter of the event.
1280 */
1281 ResetCounter(pAC, IoC, NetIndex);
1282 break;
1283
1284 case SK_PNMI_EVT_XMAC_RESET:
1285 /*
1286 * To grant continuous counter values store the current
1287 * XMAC statistic values to the entries 1..n of the
1288 * CounterOffset array. XMAC Errata #2
1289 */
1290#ifdef DEBUG
1291 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1292
1293 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1294 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1295 (unsigned int)Param.Para64));
1296 return (0);
1297 }
1298#endif
1299 PhysPortIndex = (unsigned int)Param.Para64;
1300
1301 /*
1302 * Update XMAC statistic to get fresh values
1303 */
1304 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1305 if (Ret != SK_PNMI_ERR_OK) {
1306
1307 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1308 return (0);
1309 }
1310 /*
1311 * Increment semaphore to indicate that an update was
1312 * already done
1313 */
1314 pAC->Pnmi.MacUpdatedFlag ++;
1315
1316 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1317 CounterIndex ++) {
1318
1319 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1320
1321 continue;
1322 }
1323
1324 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1325 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1326
1327 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1328 }
1329
1330 pAC->Pnmi.MacUpdatedFlag --;
1331 break;
1332
1333 case SK_PNMI_EVT_RLMT_PORT_UP:
1334 PhysPortIndex = (unsigned int)Param.Para32[0];
1335#ifdef DEBUG
1336 if (PhysPortIndex >= SK_MAX_MACS) {
1337
1338 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1339 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1340 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1341
1342 return (0);
1343 }
1344#endif /* DEBUG */
1345
1346 /*
1347 * Store a trap message in the trap buffer and generate an event for
1348 * user space applications with the SK_DRIVER_SENDEVENT macro.
1349 */
1350 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1351 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1352
1353 /* Bugfix for XMAC errata (#10620)*/
1354 if (MacType == SK_MAC_XMAC) {
1355 /* Add incremental difference to offset (#10620)*/
1356 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1357 XM_RXE_SHT_ERR, &Val32);
1358
1359 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1360 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1361 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1362 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1363 }
1364
1365 /* Tell VctStatus() that a link was up meanwhile. */
1366 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1367 break;
1368
1369 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1370 PhysPortIndex = (unsigned int)Param.Para32[0];
1371
1372#ifdef DEBUG
1373 if (PhysPortIndex >= SK_MAX_MACS) {
1374
1375 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1376 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1377 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1378
1379 return (0);
1380 }
1381#endif /* DEBUG */
1382
1383 /*
1384 * Store a trap message in the trap buffer and generate an event for
1385 * user space applications with the SK_DRIVER_SENDEVENT macro.
1386 */
1387 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1388 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1389
1390 /* Bugfix #10620 - get zero level for incremental difference */
1391 if (MacType == SK_MAC_XMAC) {
1392
1393 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1394 XM_RXE_SHT_ERR, &Val32);
1395
1396 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1397 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1398 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1399 }
1400 break;
1401
1402 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1403 PhysPortIndex = (unsigned int)Param.Para32[0];
1404 NetIndex = (SK_U32)Param.Para32[1];
1405
1406#ifdef DEBUG
1407 if (PhysPortIndex >= SK_MAX_MACS) {
1408
1409 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1410 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1411 PhysPortIndex));
1412 }
1413
1414 if (NetIndex >= pAC->Rlmt.NumNets) {
1415
1416 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1417 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1418 NetIndex));
1419 }
1420#endif /* DEBUG */
1421
1422 /*
1423 * For now, ignore event if NetIndex != 0.
1424 */
1425 if (Param.Para32[1] != 0) {
1426
1427 return (0);
1428 }
1429
1430 /*
1431 * Nothing to do if port is already inactive
1432 */
1433 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1434
1435 return (0);
1436 }
1437
1438 /*
1439 * Update statistic counters to calculate new offset for the virtual
1440 * port and increment semaphore to indicate that an update was already
1441 * done.
1442 */
1443 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1444 SK_PNMI_ERR_OK) {
1445
1446 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1447 return (0);
1448 }
1449 pAC->Pnmi.MacUpdatedFlag ++;
1450
1451 /*
1452 * Calculate new counter offset for virtual port to grant continous
1453 * counting on port switches. The virtual port consists of all currently
1454 * active ports. The port down event indicates that a port is removed
1455 * from the virtual port. Therefore add the counter value of the removed
1456 * port to the CounterOffset for the virtual port to grant the same
1457 * counter value.
1458 */
1459 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1460 CounterIndex ++) {
1461
1462 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1463
1464 continue;
1465 }
1466
1467 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1468
1469 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1470 }
1471
1472 /*
1473 * Set port to inactive
1474 */
1475 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1476
1477 pAC->Pnmi.MacUpdatedFlag --;
1478 break;
1479
1480 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1481 PhysPortIndex = (unsigned int)Param.Para32[0];
1482 NetIndex = (SK_U32)Param.Para32[1];
1483
1484#ifdef DEBUG
1485 if (PhysPortIndex >= SK_MAX_MACS) {
1486
1487 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1488 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1489 PhysPortIndex));
1490 }
1491
1492 if (NetIndex >= pAC->Rlmt.NumNets) {
1493
1494 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1495 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1496 NetIndex));
1497 }
1498#endif /* DEBUG */
1499
1500 /*
1501 * For now, ignore event if NetIndex != 0.
1502 */
1503 if (Param.Para32[1] != 0) {
1504
1505 return (0);
1506 }
1507
1508 /*
1509 * Nothing to do if port is already active
1510 */
1511 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1512
1513 return (0);
1514 }
1515
1516 /*
1517 * Statistic maintenance
1518 */
1519 pAC->Pnmi.RlmtChangeCts ++;
1520 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1521
1522 /*
1523 * Store a trap message in the trap buffer and generate an event for
1524 * user space applications with the SK_DRIVER_SENDEVENT macro.
1525 */
1526 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1527 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1528
1529 /*
1530 * Update statistic counters to calculate new offset for the virtual
1531 * port and increment semaphore to indicate that an update was
1532 * already done.
1533 */
1534 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1535 SK_PNMI_ERR_OK) {
1536
1537 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1538 return (0);
1539 }
1540 pAC->Pnmi.MacUpdatedFlag ++;
1541
1542 /*
1543 * Calculate new counter offset for virtual port to grant continous
1544 * counting on port switches. A new port is added to the virtual port.
1545 * Therefore substract the counter value of the new port from the
1546 * CounterOffset for the virtual port to grant the same value.
1547 */
1548 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1549 CounterIndex ++) {
1550
1551 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1552
1553 continue;
1554 }
1555
1556 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1557
1558 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1559 }
1560
1561 /* Set port to active */
1562 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1563
1564 pAC->Pnmi.MacUpdatedFlag --;
1565 break;
1566
1567 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1568 /*
1569 * Para.Para32[0] contains the NetIndex.
1570 */
1571
1572 /*
1573 * Store a trap message in the trap buffer and generate an event for
1574 * user space applications with the SK_DRIVER_SENDEVENT macro.
1575 */
1576 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1577 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1578 break;
1579
1580 case SK_PNMI_EVT_RLMT_SET_NETS:
1581 /*
1582 * Param.Para32[0] contains the number of Nets.
1583 * Param.Para32[1] is reserved, contains -1.
1584 */
1585 /*
1586 * Check number of nets
1587 */
1588 MaxNetNumber = pAC->GIni.GIMacsFound;
1589 if (((unsigned int)Param.Para32[0] < 1)
1590 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1591 return (SK_PNMI_ERR_UNKNOWN_NET);
1592 }
1593
1594 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1595 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1596 }
1597 else { /* dual net mode */
1598 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1599 }
1600 break;
1601
1602 case SK_PNMI_EVT_VCT_RESET:
1603 PhysPortIndex = Param.Para32[0];
1604 pPrt = &pAC->GIni.GP[PhysPortIndex];
1605 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1606
1607 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1608 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1609 if (RetCode == 2) {
1610 /*
1611 * VCT test is still running.
1612 * Start VCT timer counter again.
1613 */
1614 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1615 Param.Para32[0] = PhysPortIndex;
1616 Param.Para32[1] = -1;
1617 SkTimerStart(pAC, IoC,
1618 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1619 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1620 break;
1621 }
1622 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1623 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1624 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1625
1626 /* Copy results for later use to PNMI struct. */
1627 for (i = 0; i < 4; i++) {
1628 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1629 if ((pPrt->PMdiPairLen[i] > 35) &&
1630 (pPrt->PMdiPairLen[i] < 0xff)) {
1631 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1632 }
1633 }
1634 if ((pPrt->PMdiPairLen[i] > 35) &&
1635 (pPrt->PMdiPairLen[i] != 0xff)) {
1636 CableLength = 1000 *
1637 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1638 }
1639 else {
1640 CableLength = 0;
1641 }
1642 pVctBackupData->PMdiPairLen[i] = CableLength;
1643 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1644 }
1645
1646 Param.Para32[0] = PhysPortIndex;
1647 Param.Para32[1] = -1;
1648 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1649 SkEventDispatcher(pAC, IoC);
1650 }
1651
1652 break;
1653
1654 default:
1655 break;
1656 }
1657
1658 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1659 return (0);
1660}
1661
1662
1663/******************************************************************************
1664 *
1665 * Private functions
1666 *
1667 */
1668
1669/*****************************************************************************
1670 *
1671 * PnmiVar - Gets, presets, and sets single OIDs
1672 *
1673 * Description:
1674 * Looks up the requested OID, calls the corresponding handler
1675 * function, and passes the parameters with the get, preset, or
1676 * set command. The function is called by SkGePnmiGetVar,
1677 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1678 *
1679 * Returns:
1680 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1681 * calling functions.
1682 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1683 */
1684PNMI_STATIC int PnmiVar(
1685SK_AC *pAC, /* Pointer to adapter context */
1686SK_IOC IoC, /* IO context handle */
1687int Action, /* GET/PRESET/SET action */
1688SK_U32 Id, /* Object ID that is to be processed */
1689char *pBuf, /* Buffer used for the management data transfer */
1690unsigned int *pLen, /* Total length of pBuf management data */
1691SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1692SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1693{
1694 unsigned int TableIndex;
1695 int Ret;
1696
1697
1698 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1699
1700 *pLen = 0;
1701 return (SK_PNMI_ERR_UNKNOWN_OID);
1702 }
1703
1704 /* Check NetIndex */
1705 if (NetIndex >= pAC->Rlmt.NumNets) {
1706 return (SK_PNMI_ERR_UNKNOWN_NET);
1707 }
1708
1709 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1710
1711 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1712 Instance, TableIndex, NetIndex);
1713
1714 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1715
1716 return (Ret);
1717}
1718
1719/*****************************************************************************
1720 *
1721 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1722 *
1723 * Description:
1724 * The return value of the function will also be stored in
1725 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1726 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1727 * checks which OIDs are able to set, and calls the handler function of
1728 * the OID to perform the set. The return value of the function will
1729 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1730 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1731 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1732 *
1733 * Returns:
1734 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1735 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1736 */
1737PNMI_STATIC int PnmiStruct(
1738SK_AC *pAC, /* Pointer to adapter context */
1739SK_IOC IoC, /* IO context handle */
1740int Action, /* PRESET/SET action to be performed */
1741char *pBuf, /* Buffer used for the management data transfer */
1742unsigned int *pLen, /* Length of pBuf management data buffer */
1743SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1744{
1745 int Ret;
1746 unsigned int TableIndex;
1747 unsigned int DstOffset;
1748 unsigned int Len;
1749 unsigned int InstanceNo;
1750 unsigned int InstanceCnt;
1751 SK_U32 Instance;
1752 SK_U32 Id;
1753
1754
1755 /* Check if the passed buffer has the right size */
1756 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1757
1758 /* Check if we can return the error within the buffer */
1759 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1760
1761 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1762 (SK_U32)(-1));
1763 }
1764
1765 *pLen = SK_PNMI_STRUCT_SIZE;
1766 return (SK_PNMI_ERR_TOO_SHORT);
1767 }
1768
1769 /* Check NetIndex */
1770 if (NetIndex >= pAC->Rlmt.NumNets) {
1771 return (SK_PNMI_ERR_UNKNOWN_NET);
1772 }
1773
1774 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1775
1776 /*
1777 * Update the values of RLMT and SIRQ and increment semaphores to
1778 * indicate that an update was already done.
1779 */
1780 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1781
1782 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1783 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1784 return (Ret);
1785 }
1786
1787 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1788
1789 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1790 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1791 return (Ret);
1792 }
1793
1794 pAC->Pnmi.RlmtUpdatedFlag ++;
1795 pAC->Pnmi.SirqUpdatedFlag ++;
1796
1797 /* Preset/Set values */
1798 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1799
1800 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1801 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1802
1803 continue;
1804 }
1805
1806 InstanceNo = IdTable[TableIndex].InstanceNo;
1807 Id = IdTable[TableIndex].Id;
1808
1809 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1810 InstanceCnt ++) {
1811
1812 DstOffset = IdTable[TableIndex].Offset +
1813 (InstanceCnt - 1) *
1814 IdTable[TableIndex].StructSize;
1815
1816 /*
1817 * Because VPD multiple instance variables are
1818 * not setable we do not need to evaluate VPD
1819 * instances. Have a look to VPD instance
1820 * calculation in SkPnmiGetStruct().
1821 */
1822 Instance = (SK_U32)InstanceCnt;
1823
1824 /*
1825 * Evaluate needed buffer length
1826 */
1827 Len = 0;
1828 Ret = IdTable[TableIndex].Func(pAC, IoC,
1829 SK_PNMI_GET, IdTable[TableIndex].Id,
1830 NULL, &Len, Instance, TableIndex, NetIndex);
1831
1832 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1833
1834 break;
1835 }
1836 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1837
1838 pAC->Pnmi.RlmtUpdatedFlag --;
1839 pAC->Pnmi.SirqUpdatedFlag --;
1840
1841 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1842 SK_PNMI_SET_STAT(pBuf,
1843 SK_PNMI_ERR_GENERAL, DstOffset);
1844 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1845 return (SK_PNMI_ERR_GENERAL);
1846 }
1847 if (Id == OID_SKGE_VPD_ACTION) {
1848
1849 switch (*(pBuf + DstOffset)) {
1850
1851 case SK_PNMI_VPD_CREATE:
1852 Len = 3 + *(pBuf + DstOffset + 3);
1853 break;
1854
1855 case SK_PNMI_VPD_DELETE:
1856 Len = 3;
1857 break;
1858
1859 default:
1860 Len = 1;
1861 break;
1862 }
1863 }
1864
1865 /* Call the OID handler function */
1866 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1867 IdTable[TableIndex].Id, pBuf + DstOffset,
1868 &Len, Instance, TableIndex, NetIndex);
1869
1870 if (Ret != SK_PNMI_ERR_OK) {
1871
1872 pAC->Pnmi.RlmtUpdatedFlag --;
1873 pAC->Pnmi.SirqUpdatedFlag --;
1874
1875 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1876 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1877 DstOffset);
1878 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1879 return (SK_PNMI_ERR_BAD_VALUE);
1880 }
1881 }
1882 }
1883
1884 pAC->Pnmi.RlmtUpdatedFlag --;
1885 pAC->Pnmi.SirqUpdatedFlag --;
1886
1887 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1888 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1889 return (SK_PNMI_ERR_OK);
1890}
1891
1892/*****************************************************************************
1893 *
1894 * LookupId - Lookup an OID in the IdTable
1895 *
1896 * Description:
1897 * Scans the IdTable to find the table entry of an OID.
1898 *
1899 * Returns:
1900 * The table index or -1 if not found.
1901 */
1902PNMI_STATIC int LookupId(
1903SK_U32 Id) /* Object identifier to be searched */
1904{
1905 int i;
1906
1907 for (i = 0; i < ID_TABLE_SIZE; i++) {
1908
1909 if (IdTable[i].Id == Id) {
1910
1911 return i;
1912 }
1913 }
1914
1915 return (-1);
1916}
1917
1918/*****************************************************************************
1919 *
1920 * OidStruct - Handler of OID_SKGE_ALL_DATA
1921 *
1922 * Description:
1923 * This OID performs a Get/Preset/SetStruct call and returns all data
1924 * in a SK_PNMI_STRUCT_DATA structure.
1925 *
1926 * Returns:
1927 * SK_PNMI_ERR_OK The request was successfully performed.
1928 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1929 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1930 * the correct data (e.g. a 32bit value is
1931 * needed, but a 16 bit value was passed).
1932 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1933 * value range.
1934 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1935 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1936 * exist (e.g. port instance 3 on a two port
1937 * adapter.
1938 */
1939PNMI_STATIC int OidStruct(
1940SK_AC *pAC, /* Pointer to adapter context */
1941SK_IOC IoC, /* IO context handle */
1942int Action, /* GET/PRESET/SET action */
1943SK_U32 Id, /* Object ID that is to be processed */
1944char *pBuf, /* Buffer used for the management data transfer */
1945unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1946SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1947unsigned int TableIndex, /* Index to the Id table */
1948SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1949{
1950 if (Id != OID_SKGE_ALL_DATA) {
1951
1952 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1953 SK_PNMI_ERR003MSG);
1954
1955 *pLen = 0;
1956 return (SK_PNMI_ERR_GENERAL);
1957 }
1958
1959 /*
1960 * Check instance. We only handle single instance variables
1961 */
1962 if (Instance != (SK_U32)(-1) && Instance != 1) {
1963
1964 *pLen = 0;
1965 return (SK_PNMI_ERR_UNKNOWN_INST);
1966 }
1967
1968 switch (Action) {
1969
1970 case SK_PNMI_GET:
1971 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1972
1973 case SK_PNMI_PRESET:
1974 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1975
1976 case SK_PNMI_SET:
1977 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1978 }
1979
1980 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1981
1982 *pLen = 0;
1983 return (SK_PNMI_ERR_GENERAL);
1984}
1985
1986/*****************************************************************************
1987 *
1988 * Perform - OID handler of OID_SKGE_ACTION
1989 *
1990 * Description:
1991 * None.
1992 *
1993 * Returns:
1994 * SK_PNMI_ERR_OK The request was successfully performed.
1995 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1996 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1997 * the correct data (e.g. a 32bit value is
1998 * needed, but a 16 bit value was passed).
1999 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2000 * value range.
2001 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2002 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2003 * exist (e.g. port instance 3 on a two port
2004 * adapter.
2005 */
2006PNMI_STATIC int Perform(
2007SK_AC *pAC, /* Pointer to adapter context */
2008SK_IOC IoC, /* IO context handle */
2009int Action, /* GET/PRESET/SET action */
2010SK_U32 Id, /* Object ID that is to be processed */
2011char *pBuf, /* Buffer used for the management data transfer */
2012unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2013SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2014unsigned int TableIndex, /* Index to the Id table */
2015SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2016{
2017 int Ret;
2018 SK_U32 ActionOp;
2019
2020
2021 /*
2022 * Check instance. We only handle single instance variables
2023 */
2024 if (Instance != (SK_U32)(-1) && Instance != 1) {
2025
2026 *pLen = 0;
2027 return (SK_PNMI_ERR_UNKNOWN_INST);
2028 }
2029
2030 if (*pLen < sizeof(SK_U32)) {
2031
2032 *pLen = sizeof(SK_U32);
2033 return (SK_PNMI_ERR_TOO_SHORT);
2034 }
2035
2036 /* Check if a get should be performed */
2037 if (Action == SK_PNMI_GET) {
2038
2039 /* A get is easy. We always return the same value */
2040 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2041 SK_PNMI_STORE_U32(pBuf, ActionOp);
2042 *pLen = sizeof(SK_U32);
2043
2044 return (SK_PNMI_ERR_OK);
2045 }
2046
2047 /* Continue with PRESET/SET action */
2048 if (*pLen > sizeof(SK_U32)) {
2049
2050 return (SK_PNMI_ERR_BAD_VALUE);
2051 }
2052
2053 /* Check if the command is a known one */
2054 SK_PNMI_READ_U32(pBuf, ActionOp);
2055 if (*pLen > sizeof(SK_U32) ||
2056 (ActionOp != SK_PNMI_ACT_IDLE &&
2057 ActionOp != SK_PNMI_ACT_RESET &&
2058 ActionOp != SK_PNMI_ACT_SELFTEST &&
2059 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2060
2061 *pLen = 0;
2062 return (SK_PNMI_ERR_BAD_VALUE);
2063 }
2064
2065 /* A preset ends here */
2066 if (Action == SK_PNMI_PRESET) {
2067
2068 return (SK_PNMI_ERR_OK);
2069 }
2070
2071 switch (ActionOp) {
2072
2073 case SK_PNMI_ACT_IDLE:
2074 /* Nothing to do */
2075 break;
2076
2077 case SK_PNMI_ACT_RESET:
2078 /*
2079 * Perform a driver reset or something that comes near
2080 * to this.
2081 */
2082 Ret = SK_DRIVER_RESET(pAC, IoC);
2083 if (Ret != 0) {
2084
2085 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2086 SK_PNMI_ERR005MSG);
2087
2088 return (SK_PNMI_ERR_GENERAL);
2089 }
2090 break;
2091
2092 case SK_PNMI_ACT_SELFTEST:
2093 /*
2094 * Perform a driver selftest or something similar to this.
2095 * Currently this feature is not used and will probably
2096 * implemented in another way.
2097 */
2098 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2099 pAC->Pnmi.TestResult = Ret;
2100 break;
2101
2102 case SK_PNMI_ACT_RESETCNT:
2103 /* Set all counters and timestamps to zero */
2104 ResetCounter(pAC, IoC, NetIndex);
2105 break;
2106
2107 default:
2108 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2109 SK_PNMI_ERR006MSG);
2110
2111 return (SK_PNMI_ERR_GENERAL);
2112 }
2113
2114 return (SK_PNMI_ERR_OK);
2115}
2116
2117/*****************************************************************************
2118 *
2119 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2120 *
2121 * Description:
2122 * Retrieves the statistic values of the virtual port (logical
2123 * index 0). Only special OIDs of NDIS are handled which consist
2124 * of a 32 bit instead of a 64 bit value. The OIDs are public
2125 * because perhaps some other platform can use them too.
2126 *
2127 * Returns:
2128 * SK_PNMI_ERR_OK The request was successfully performed.
2129 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2130 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2131 * the correct data (e.g. a 32bit value is
2132 * needed, but a 16 bit value was passed).
2133 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2134 * exist (e.g. port instance 3 on a two port
2135 * adapter.
2136 */
2137PNMI_STATIC int Mac8023Stat(
2138SK_AC *pAC, /* Pointer to adapter context */
2139SK_IOC IoC, /* IO context handle */
2140int Action, /* GET/PRESET/SET action */
2141SK_U32 Id, /* Object ID that is to be processed */
2142char *pBuf, /* Buffer used for the management data transfer */
2143unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2144SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2145unsigned int TableIndex, /* Index to the Id table */
2146SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2147{
2148 int Ret;
2149 SK_U64 StatVal;
2150 SK_U32 StatVal32;
2151 SK_BOOL Is64BitReq = SK_FALSE;
2152
2153 /*
2154 * Only the active Mac is returned
2155 */
2156 if (Instance != (SK_U32)(-1) && Instance != 1) {
2157
2158 *pLen = 0;
2159 return (SK_PNMI_ERR_UNKNOWN_INST);
2160 }
2161
2162 /*
2163 * Check action type
2164 */
2165 if (Action != SK_PNMI_GET) {
2166
2167 *pLen = 0;
2168 return (SK_PNMI_ERR_READ_ONLY);
2169 }
2170
2171 /* Check length */
2172 switch (Id) {
2173
2174 case OID_802_3_PERMANENT_ADDRESS:
2175 case OID_802_3_CURRENT_ADDRESS:
2176 if (*pLen < sizeof(SK_MAC_ADDR)) {
2177
2178 *pLen = sizeof(SK_MAC_ADDR);
2179 return (SK_PNMI_ERR_TOO_SHORT);
2180 }
2181 break;
2182
2183 default:
2184#ifndef SK_NDIS_64BIT_CTR
2185 if (*pLen < sizeof(SK_U32)) {
2186 *pLen = sizeof(SK_U32);
2187 return (SK_PNMI_ERR_TOO_SHORT);
2188 }
2189
2190#else /* SK_NDIS_64BIT_CTR */
2191
2192 /* for compatibility, at least 32bit are required for OID */
2193 if (*pLen < sizeof(SK_U32)) {
2194 /*
2195 * but indicate handling for 64bit values,
2196 * if insufficient space is provided
2197 */
2198 *pLen = sizeof(SK_U64);
2199 return (SK_PNMI_ERR_TOO_SHORT);
2200 }
2201
2202 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2203#endif /* SK_NDIS_64BIT_CTR */
2204 break;
2205 }
2206
2207 /*
2208 * Update all statistics, because we retrieve virtual MAC, which
2209 * consists of multiple physical statistics and increment semaphore
2210 * to indicate that an update was already done.
2211 */
2212 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2213 if ( Ret != SK_PNMI_ERR_OK) {
2214
2215 *pLen = 0;
2216 return (Ret);
2217 }
2218 pAC->Pnmi.MacUpdatedFlag ++;
2219
2220 /*
2221 * Get value (MAC Index 0 identifies the virtual MAC)
2222 */
2223 switch (Id) {
2224
2225 case OID_802_3_PERMANENT_ADDRESS:
2226 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2227 *pLen = sizeof(SK_MAC_ADDR);
2228 break;
2229
2230 case OID_802_3_CURRENT_ADDRESS:
2231 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2232 *pLen = sizeof(SK_MAC_ADDR);
2233 break;
2234
2235 default:
2236 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2237
2238 /* by default 32bit values are evaluated */
2239 if (!Is64BitReq) {
2240 StatVal32 = (SK_U32)StatVal;
2241 SK_PNMI_STORE_U32(pBuf, StatVal32);
2242 *pLen = sizeof(SK_U32);
2243 }
2244 else {
2245 SK_PNMI_STORE_U64(pBuf, StatVal);
2246 *pLen = sizeof(SK_U64);
2247 }
2248 break;
2249 }
2250
2251 pAC->Pnmi.MacUpdatedFlag --;
2252
2253 return (SK_PNMI_ERR_OK);
2254}
2255
2256/*****************************************************************************
2257 *
2258 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2259 *
2260 * Description:
2261 * Retrieves the MAC statistic data.
2262 *
2263 * Returns:
2264 * SK_PNMI_ERR_OK The request was successfully performed.
2265 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2266 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2267 * the correct data (e.g. a 32bit value is
2268 * needed, but a 16 bit value was passed).
2269 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2270 * exist (e.g. port instance 3 on a two port
2271 * adapter.
2272 */
2273PNMI_STATIC int MacPrivateStat(
2274SK_AC *pAC, /* Pointer to adapter context */
2275SK_IOC IoC, /* IO context handle */
2276int Action, /* GET/PRESET/SET action */
2277SK_U32 Id, /* Object ID that is to be processed */
2278char *pBuf, /* Buffer used for the management data transfer */
2279unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2280SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2281unsigned int TableIndex, /* Index to the Id table */
2282SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2283{
2284 unsigned int LogPortMax;
2285 unsigned int LogPortIndex;
2286 unsigned int PhysPortMax;
2287 unsigned int Limit;
2288 unsigned int Offset;
2289 int MacType;
2290 int Ret;
2291 SK_U64 StatVal;
2292
2293
2294
2295 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2296 PhysPortMax = pAC->GIni.GIMacsFound;
2297 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2298
2299 MacType = pAC->GIni.GIMacType;
2300
2301 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2302 LogPortMax--;
2303 }
2304
2305 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2306 /* Check instance range */
2307 if ((Instance < 1) || (Instance > LogPortMax)) {
2308
2309 *pLen = 0;
2310 return (SK_PNMI_ERR_UNKNOWN_INST);
2311 }
2312 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2313 Limit = LogPortIndex + 1;
2314 }
2315
2316 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2317
2318 LogPortIndex = 0;
2319 Limit = LogPortMax;
2320 }
2321
2322 /* Check action */
2323 if (Action != SK_PNMI_GET) {
2324
2325 *pLen = 0;
2326 return (SK_PNMI_ERR_READ_ONLY);
2327 }
2328
2329 /* Check length */
2330 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2331
2332 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2333 return (SK_PNMI_ERR_TOO_SHORT);
2334 }
2335
2336 /*
2337 * Update MAC statistic and increment semaphore to indicate that
2338 * an update was already done.
2339 */
2340 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2341 if (Ret != SK_PNMI_ERR_OK) {
2342
2343 *pLen = 0;
2344 return (Ret);
2345 }
2346 pAC->Pnmi.MacUpdatedFlag ++;
2347
2348 /* Get value */
2349 Offset = 0;
2350 for (; LogPortIndex < Limit; LogPortIndex ++) {
2351
2352 switch (Id) {
2353
2354/* XXX not yet implemented due to XMAC problems
2355 case OID_SKGE_STAT_TX_UTIL:
2356 return (SK_PNMI_ERR_GENERAL);
2357*/
2358/* XXX not yet implemented due to XMAC problems
2359 case OID_SKGE_STAT_RX_UTIL:
2360 return (SK_PNMI_ERR_GENERAL);
2361*/
2362 case OID_SKGE_STAT_RX:
2363 if (MacType == SK_MAC_GMAC) {
2364 StatVal =
2365 GetStatVal(pAC, IoC, LogPortIndex,
2366 SK_PNMI_HRX_BROADCAST, NetIndex) +
2367 GetStatVal(pAC, IoC, LogPortIndex,
2368 SK_PNMI_HRX_MULTICAST, NetIndex) +
2369 GetStatVal(pAC, IoC, LogPortIndex,
2370 SK_PNMI_HRX_UNICAST, NetIndex) +
2371 GetStatVal(pAC, IoC, LogPortIndex,
2372 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2373 }
2374 else {
2375 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2376 IdTable[TableIndex].Param, NetIndex);
2377 }
2378 break;
2379
2380 case OID_SKGE_STAT_TX:
2381 if (MacType == SK_MAC_GMAC) {
2382 StatVal =
2383 GetStatVal(pAC, IoC, LogPortIndex,
2384 SK_PNMI_HTX_BROADCAST, NetIndex) +
2385 GetStatVal(pAC, IoC, LogPortIndex,
2386 SK_PNMI_HTX_MULTICAST, NetIndex) +
2387 GetStatVal(pAC, IoC, LogPortIndex,
2388 SK_PNMI_HTX_UNICAST, NetIndex);
2389 }
2390 else {
2391 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2392 IdTable[TableIndex].Param, NetIndex);
2393 }
2394 break;
2395
2396 default:
2397 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2398 IdTable[TableIndex].Param, NetIndex);
2399 }
2400 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2401
2402 Offset += sizeof(SK_U64);
2403 }
2404 *pLen = Offset;
2405
2406 pAC->Pnmi.MacUpdatedFlag --;
2407
2408 return (SK_PNMI_ERR_OK);
2409}
2410
2411/*****************************************************************************
2412 *
2413 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2414 *
2415 * Description:
2416 * Get/Presets/Sets the current and factory MAC address. The MAC
2417 * address of the virtual port, which is reported to the OS, may
2418 * not be changed, but the physical ones. A set to the virtual port
2419 * will be ignored. No error should be reported because otherwise
2420 * a multiple instance set (-1) would always fail.
2421 *
2422 * Returns:
2423 * SK_PNMI_ERR_OK The request was successfully performed.
2424 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2425 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2426 * the correct data (e.g. a 32bit value is
2427 * needed, but a 16 bit value was passed).
2428 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2429 * value range.
2430 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2431 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2432 * exist (e.g. port instance 3 on a two port
2433 * adapter.
2434 */
2435PNMI_STATIC int Addr(
2436SK_AC *pAC, /* Pointer to adapter context */
2437SK_IOC IoC, /* IO context handle */
2438int Action, /* GET/PRESET/SET action */
2439SK_U32 Id, /* Object ID that is to be processed */
2440char *pBuf, /* Buffer used for the management data transfer */
2441unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2442SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2443unsigned int TableIndex, /* Index to the Id table */
2444SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2445{
2446 int Ret;
2447 unsigned int LogPortMax;
2448 unsigned int PhysPortMax;
2449 unsigned int LogPortIndex;
2450 unsigned int PhysPortIndex;
2451 unsigned int Limit;
2452 unsigned int Offset = 0;
2453
2454 /*
2455 * Calculate instance if wished. MAC index 0 is the virtual
2456 * MAC.
2457 */
2458 PhysPortMax = pAC->GIni.GIMacsFound;
2459 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2460
2461 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2462 LogPortMax--;
2463 }
2464
2465 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2466 /* Check instance range */
2467 if ((Instance < 1) || (Instance > LogPortMax)) {
2468
2469 *pLen = 0;
2470 return (SK_PNMI_ERR_UNKNOWN_INST);
2471 }
2472 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2473 Limit = LogPortIndex + 1;
2474 }
2475 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2476
2477 LogPortIndex = 0;
2478 Limit = LogPortMax;
2479 }
2480
2481 /*
2482 * Perform Action
2483 */
2484 if (Action == SK_PNMI_GET) {
2485
2486 /* Check length */
2487 if (*pLen < (Limit - LogPortIndex) * 6) {
2488
2489 *pLen = (Limit - LogPortIndex) * 6;
2490 return (SK_PNMI_ERR_TOO_SHORT);
2491 }
2492
2493 /*
2494 * Get value
2495 */
2496 for (; LogPortIndex < Limit; LogPortIndex ++) {
2497
2498 switch (Id) {
2499
2500 case OID_SKGE_PHYS_CUR_ADDR:
2501 if (LogPortIndex == 0) {
2502 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2503 }
2504 else {
2505 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2506
2507 CopyMac(pBuf + Offset,
2508 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2509 }
2510 Offset += 6;
2511 break;
2512
2513 case OID_SKGE_PHYS_FAC_ADDR:
2514 if (LogPortIndex == 0) {
2515 CopyMac(pBuf + Offset,
2516 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2517 }
2518 else {
2519 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2520 pAC, LogPortIndex);
2521
2522 CopyMac(pBuf + Offset,
2523 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2524 }
2525 Offset += 6;
2526 break;
2527
2528 default:
2529 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2530 SK_PNMI_ERR008MSG);
2531
2532 *pLen = 0;
2533 return (SK_PNMI_ERR_GENERAL);
2534 }
2535 }
2536
2537 *pLen = Offset;
2538 }
2539 else {
2540 /*
2541 * The logical MAC address may not be changed only
2542 * the physical ones
2543 */
2544 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2545
2546 *pLen = 0;
2547 return (SK_PNMI_ERR_READ_ONLY);
2548 }
2549
2550 /*
2551 * Only the current address may be changed
2552 */
2553 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2554
2555 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2556 SK_PNMI_ERR009MSG);
2557
2558 *pLen = 0;
2559 return (SK_PNMI_ERR_GENERAL);
2560 }
2561
2562 /* Check length */
2563 if (*pLen < (Limit - LogPortIndex) * 6) {
2564
2565 *pLen = (Limit - LogPortIndex) * 6;
2566 return (SK_PNMI_ERR_TOO_SHORT);
2567 }
2568 if (*pLen > (Limit - LogPortIndex) * 6) {
2569
2570 *pLen = 0;
2571 return (SK_PNMI_ERR_BAD_VALUE);
2572 }
2573
2574 /*
2575 * Check Action
2576 */
2577 if (Action == SK_PNMI_PRESET) {
2578
2579 *pLen = 0;
2580 return (SK_PNMI_ERR_OK);
2581 }
2582
2583 /*
2584 * Set OID_SKGE_MAC_CUR_ADDR
2585 */
2586 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2587
2588 /*
2589 * A set to virtual port and set of broadcast
2590 * address will be ignored
2591 */
2592 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2593 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2594
2595 continue;
2596 }
2597
2598 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2599 LogPortIndex);
2600
2601 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2602 (SK_MAC_ADDR *)(pBuf + Offset),
2603 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2604 SK_ADDR_PHYSICAL_ADDRESS));
2605 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2606
2607 return (SK_PNMI_ERR_GENERAL);
2608 }
2609 }
2610 *pLen = Offset;
2611 }
2612
2613 return (SK_PNMI_ERR_OK);
2614}
2615
2616/*****************************************************************************
2617 *
2618 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2619 *
2620 * Description:
2621 * Retrieves the statistic values of the CSUM module. The CSUM data
2622 * structure must be available in the SK_AC even if the CSUM module
2623 * is not included, because PNMI reads the statistic data from the
2624 * CSUM part of SK_AC directly.
2625 *
2626 * Returns:
2627 * SK_PNMI_ERR_OK The request was successfully performed.
2628 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2629 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2630 * the correct data (e.g. a 32bit value is
2631 * needed, but a 16 bit value was passed).
2632 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2633 * exist (e.g. port instance 3 on a two port
2634 * adapter.
2635 */
2636PNMI_STATIC int CsumStat(
2637SK_AC *pAC, /* Pointer to adapter context */
2638SK_IOC IoC, /* IO context handle */
2639int Action, /* GET/PRESET/SET action */
2640SK_U32 Id, /* Object ID that is to be processed */
2641char *pBuf, /* Buffer used for the management data transfer */
2642unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2643SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2644unsigned int TableIndex, /* Index to the Id table */
2645SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2646{
2647 unsigned int Index;
2648 unsigned int Limit;
2649 unsigned int Offset = 0;
2650 SK_U64 StatVal;
2651
2652
2653 /*
2654 * Calculate instance if wished
2655 */
2656 if (Instance != (SK_U32)(-1)) {
2657
2658 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2659
2660 *pLen = 0;
2661 return (SK_PNMI_ERR_UNKNOWN_INST);
2662 }
2663 Index = (unsigned int)Instance - 1;
2664 Limit = Index + 1;
2665 }
2666 else {
2667 Index = 0;
2668 Limit = SKCS_NUM_PROTOCOLS;
2669 }
2670
2671 /*
2672 * Check action
2673 */
2674 if (Action != SK_PNMI_GET) {
2675
2676 *pLen = 0;
2677 return (SK_PNMI_ERR_READ_ONLY);
2678 }
2679
2680 /* Check length */
2681 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2682
2683 *pLen = (Limit - Index) * sizeof(SK_U64);
2684 return (SK_PNMI_ERR_TOO_SHORT);
2685 }
2686
2687 /*
2688 * Get value
2689 */
2690 for (; Index < Limit; Index ++) {
2691
2692 switch (Id) {
2693
2694 case OID_SKGE_CHKSM_RX_OK_CTS:
2695 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2696 break;
2697
2698 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2699 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2700 break;
2701
2702 case OID_SKGE_CHKSM_RX_ERR_CTS:
2703 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2704 break;
2705
2706 case OID_SKGE_CHKSM_TX_OK_CTS:
2707 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2708 break;
2709
2710 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2711 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2712 break;
2713
2714 default:
2715 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2716 SK_PNMI_ERR010MSG);
2717
2718 *pLen = 0;
2719 return (SK_PNMI_ERR_GENERAL);
2720 }
2721
2722 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2723 Offset += sizeof(SK_U64);
2724 }
2725
2726 /*
2727 * Store used buffer space
2728 */
2729 *pLen = Offset;
2730
2731 return (SK_PNMI_ERR_OK);
2732}
2733
2734/*****************************************************************************
2735 *
2736 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2737 *
2738 * Description:
2739 * Retrieves the statistic values of the I2C module, which handles
2740 * the temperature and voltage sensors.
2741 *
2742 * Returns:
2743 * SK_PNMI_ERR_OK The request was successfully performed.
2744 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2745 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2746 * the correct data (e.g. a 32bit value is
2747 * needed, but a 16 bit value was passed).
2748 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2749 * exist (e.g. port instance 3 on a two port
2750 * adapter.
2751 */
2752PNMI_STATIC int SensorStat(
2753SK_AC *pAC, /* Pointer to adapter context */
2754SK_IOC IoC, /* IO context handle */
2755int Action, /* GET/PRESET/SET action */
2756SK_U32 Id, /* Object ID that is to be processed */
2757char *pBuf, /* Buffer used for the management data transfer */
2758unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2759SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2760unsigned int TableIndex, /* Index to the Id table */
2761SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2762{
2763 unsigned int i;
2764 unsigned int Index;
2765 unsigned int Limit;
2766 unsigned int Offset;
2767 unsigned int Len;
2768 SK_U32 Val32;
2769 SK_U64 Val64;
2770
2771
2772 /*
2773 * Calculate instance if wished
2774 */
2775 if ((Instance != (SK_U32)(-1))) {
2776
2777 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2778
2779 *pLen = 0;
2780 return (SK_PNMI_ERR_UNKNOWN_INST);
2781 }
2782
2783 Index = (unsigned int)Instance -1;
2784 Limit = (unsigned int)Instance;
2785 }
2786 else {
2787 Index = 0;
2788 Limit = (unsigned int) pAC->I2c.MaxSens;
2789 }
2790
2791 /*
2792 * Check action
2793 */
2794 if (Action != SK_PNMI_GET) {
2795
2796 *pLen = 0;
2797 return (SK_PNMI_ERR_READ_ONLY);
2798 }
2799
2800 /* Check length */
2801 switch (Id) {
2802
2803 case OID_SKGE_SENSOR_VALUE:
2804 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2805 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2806 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2807 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2808 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2809
2810 *pLen = (Limit - Index) * sizeof(SK_U32);
2811 return (SK_PNMI_ERR_TOO_SHORT);
2812 }
2813 break;
2814
2815 case OID_SKGE_SENSOR_DESCR:
2816 for (Offset = 0, i = Index; i < Limit; i ++) {
2817
2818 Len = (unsigned int)
2819 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2820 if (Len >= SK_PNMI_STRINGLEN2) {
2821
2822 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2823 SK_PNMI_ERR011MSG);
2824
2825 *pLen = 0;
2826 return (SK_PNMI_ERR_GENERAL);
2827 }
2828 Offset += Len;
2829 }
2830 if (*pLen < Offset) {
2831
2832 *pLen = Offset;
2833 return (SK_PNMI_ERR_TOO_SHORT);
2834 }
2835 break;
2836
2837 case OID_SKGE_SENSOR_INDEX:
2838 case OID_SKGE_SENSOR_TYPE:
2839 case OID_SKGE_SENSOR_STATUS:
2840 if (*pLen < Limit - Index) {
2841
2842 *pLen = Limit - Index;
2843 return (SK_PNMI_ERR_TOO_SHORT);
2844 }
2845 break;
2846
2847 case OID_SKGE_SENSOR_WAR_CTS:
2848 case OID_SKGE_SENSOR_WAR_TIME:
2849 case OID_SKGE_SENSOR_ERR_CTS:
2850 case OID_SKGE_SENSOR_ERR_TIME:
2851 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2852
2853 *pLen = (Limit - Index) * sizeof(SK_U64);
2854 return (SK_PNMI_ERR_TOO_SHORT);
2855 }
2856 break;
2857
2858 default:
2859 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2860 SK_PNMI_ERR012MSG);
2861
2862 *pLen = 0;
2863 return (SK_PNMI_ERR_GENERAL);
2864
2865 }
2866
2867 /*
2868 * Get value
2869 */
2870 for (Offset = 0; Index < Limit; Index ++) {
2871
2872 switch (Id) {
2873
2874 case OID_SKGE_SENSOR_INDEX:
2875 *(pBuf + Offset) = (char)Index;
2876 Offset += sizeof(char);
2877 break;
2878
2879 case OID_SKGE_SENSOR_DESCR:
2880 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2881 SK_MEMCPY(pBuf + Offset + 1,
2882 pAC->I2c.SenTable[Index].SenDesc, Len);
2883 *(pBuf + Offset) = (char)Len;
2884 Offset += Len + 1;
2885 break;
2886
2887 case OID_SKGE_SENSOR_TYPE:
2888 *(pBuf + Offset) =
2889 (char)pAC->I2c.SenTable[Index].SenType;
2890 Offset += sizeof(char);
2891 break;
2892
2893 case OID_SKGE_SENSOR_VALUE:
2894 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2895 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2896 Offset += sizeof(SK_U32);
2897 break;
2898
2899 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2900 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2901 SenThreWarnLow;
2902 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2903 Offset += sizeof(SK_U32);
2904 break;
2905
2906 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2907 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2908 SenThreWarnHigh;
2909 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2910 Offset += sizeof(SK_U32);
2911 break;
2912
2913 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2914 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2915 SenThreErrLow;
2916 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2917 Offset += sizeof(SK_U32);
2918 break;
2919
2920 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2921 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2922 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2923 Offset += sizeof(SK_U32);
2924 break;
2925
2926 case OID_SKGE_SENSOR_STATUS:
2927 *(pBuf + Offset) =
2928 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2929 Offset += sizeof(char);
2930 break;
2931
2932 case OID_SKGE_SENSOR_WAR_CTS:
2933 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2934 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2935 Offset += sizeof(SK_U64);
2936 break;
2937
2938 case OID_SKGE_SENSOR_ERR_CTS:
2939 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2940 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2941 Offset += sizeof(SK_U64);
2942 break;
2943
2944 case OID_SKGE_SENSOR_WAR_TIME:
2945 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2946 SenBegWarnTS);
2947 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2948 Offset += sizeof(SK_U64);
2949 break;
2950
2951 case OID_SKGE_SENSOR_ERR_TIME:
2952 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2953 SenBegErrTS);
2954 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2955 Offset += sizeof(SK_U64);
2956 break;
2957
2958 default:
2959 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2960 ("SensorStat: Unknown OID should be handled before"));
2961
2962 return (SK_PNMI_ERR_GENERAL);
2963 }
2964 }
2965
2966 /*
2967 * Store used buffer space
2968 */
2969 *pLen = Offset;
2970
2971 return (SK_PNMI_ERR_OK);
2972}
2973
2974/*****************************************************************************
2975 *
2976 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2977 *
2978 * Description:
2979 * Get/preset/set of VPD data. As instance the name of a VPD key
2980 * can be passed. The Instance parameter is a SK_U32 and can be
2981 * used as a string buffer for the VPD key, because their maximum
2982 * length is 4 byte.
2983 *
2984 * Returns:
2985 * SK_PNMI_ERR_OK The request was successfully performed.
2986 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2987 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2988 * the correct data (e.g. a 32bit value is
2989 * needed, but a 16 bit value was passed).
2990 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2991 * value range.
2992 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2993 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2994 * exist (e.g. port instance 3 on a two port
2995 * adapter.
2996 */
2997PNMI_STATIC int Vpd(
2998SK_AC *pAC, /* Pointer to adapter context */
2999SK_IOC IoC, /* IO context handle */
3000int Action, /* GET/PRESET/SET action */
3001SK_U32 Id, /* Object ID that is to be processed */
3002char *pBuf, /* Buffer used for the management data transfer */
3003unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3004SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3005unsigned int TableIndex, /* Index to the Id table */
3006SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3007{
3008 SK_VPD_STATUS *pVpdStatus;
3009 unsigned int BufLen;
3010 char Buf[256];
3011 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3012 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3013 unsigned int KeyNo;
3014 unsigned int Offset;
3015 unsigned int Index;
3016 unsigned int FirstIndex;
3017 unsigned int LastIndex;
3018 unsigned int Len;
3019 int Ret;
3020 SK_U32 Val32;
3021
3022 /*
3023 * Get array of all currently stored VPD keys
3024 */
3025 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3026 if (Ret != SK_PNMI_ERR_OK) {
3027 *pLen = 0;
3028 return (Ret);
3029 }
3030
3031 /*
3032 * If instance is not -1, try to find the requested VPD key for
3033 * the multiple instance variables. The other OIDs as for example
3034 * OID VPD_ACTION are single instance variables and must be
3035 * handled separatly.
3036 */
3037 FirstIndex = 0;
3038 LastIndex = KeyNo;
3039
3040 if ((Instance != (SK_U32)(-1))) {
3041
3042 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3043 Id == OID_SKGE_VPD_ACCESS) {
3044
3045 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3046 KeyStr[4] = 0;
3047
3048 for (Index = 0; Index < KeyNo; Index ++) {
3049
3050 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3051 FirstIndex = Index;
3052 LastIndex = Index+1;
3053 break;
3054 }
3055 }
3056 if (Index == KeyNo) {
3057
3058 *pLen = 0;
3059 return (SK_PNMI_ERR_UNKNOWN_INST);
3060 }
3061 }
3062 else if (Instance != 1) {
3063
3064 *pLen = 0;
3065 return (SK_PNMI_ERR_UNKNOWN_INST);
3066 }
3067 }
3068
3069 /*
3070 * Get value, if a query should be performed
3071 */
3072 if (Action == SK_PNMI_GET) {
3073
3074 switch (Id) {
3075
3076 case OID_SKGE_VPD_FREE_BYTES:
3077 /* Check length of buffer */
3078 if (*pLen < sizeof(SK_U32)) {
3079
3080 *pLen = sizeof(SK_U32);
3081 return (SK_PNMI_ERR_TOO_SHORT);
3082 }
3083 /* Get number of free bytes */
3084 pVpdStatus = VpdStat(pAC, IoC);
3085 if (pVpdStatus == NULL) {
3086
3087 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3088 SK_PNMI_ERR017MSG);
3089
3090 *pLen = 0;
3091 return (SK_PNMI_ERR_GENERAL);
3092 }
3093 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3094
3095 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3096 SK_PNMI_ERR018MSG);
3097
3098 *pLen = 0;
3099 return (SK_PNMI_ERR_GENERAL);
3100 }
3101
3102 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3103 SK_PNMI_STORE_U32(pBuf, Val32);
3104 *pLen = sizeof(SK_U32);
3105 break;
3106
3107 case OID_SKGE_VPD_ENTRIES_LIST:
3108 /* Check length */
3109 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3110
3111 Len += SK_STRLEN(KeyArr[Index]) + 1;
3112 }
3113 if (*pLen < Len) {
3114
3115 *pLen = Len;
3116 return (SK_PNMI_ERR_TOO_SHORT);
3117 }
3118
3119 /* Get value */
3120 *(pBuf) = (char)Len - 1;
3121 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3122
3123 Len = SK_STRLEN(KeyArr[Index]);
3124 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3125
3126 Offset += Len;
3127
3128 if (Index < KeyNo - 1) {
3129
3130 *(pBuf + Offset) = ' ';
3131 Offset ++;
3132 }
3133 }
3134 *pLen = Offset;
3135 break;
3136
3137 case OID_SKGE_VPD_ENTRIES_NUMBER:
3138 /* Check length */
3139 if (*pLen < sizeof(SK_U32)) {
3140
3141 *pLen = sizeof(SK_U32);
3142 return (SK_PNMI_ERR_TOO_SHORT);
3143 }
3144
3145 Val32 = (SK_U32)KeyNo;
3146 SK_PNMI_STORE_U32(pBuf, Val32);
3147 *pLen = sizeof(SK_U32);
3148 break;
3149
3150 case OID_SKGE_VPD_KEY:
3151 /* Check buffer length, if it is large enough */
3152 for (Len = 0, Index = FirstIndex;
3153 Index < LastIndex; Index ++) {
3154
3155 Len += SK_STRLEN(KeyArr[Index]) + 1;
3156 }
3157 if (*pLen < Len) {
3158
3159 *pLen = Len;
3160 return (SK_PNMI_ERR_TOO_SHORT);
3161 }
3162
3163 /*
3164 * Get the key to an intermediate buffer, because
3165 * we have to prepend a length byte.
3166 */
3167 for (Offset = 0, Index = FirstIndex;
3168 Index < LastIndex; Index ++) {
3169
3170 Len = SK_STRLEN(KeyArr[Index]);
3171
3172 *(pBuf + Offset) = (char)Len;
3173 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3174 Len);
3175 Offset += Len + 1;
3176 }
3177 *pLen = Offset;
3178 break;
3179
3180 case OID_SKGE_VPD_VALUE:
3181 /* Check the buffer length if it is large enough */
3182 for (Offset = 0, Index = FirstIndex;
3183 Index < LastIndex; Index ++) {
3184
3185 BufLen = 256;
3186 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3187 (int *)&BufLen) > 0 ||
3188 BufLen >= SK_PNMI_VPD_DATALEN) {
3189
3190 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3191 SK_PNMI_ERR021,
3192 SK_PNMI_ERR021MSG);
3193
3194 return (SK_PNMI_ERR_GENERAL);
3195 }
3196 Offset += BufLen + 1;
3197 }
3198 if (*pLen < Offset) {
3199
3200 *pLen = Offset;
3201 return (SK_PNMI_ERR_TOO_SHORT);
3202 }
3203
3204 /*
3205 * Get the value to an intermediate buffer, because
3206 * we have to prepend a length byte.
3207 */
3208 for (Offset = 0, Index = FirstIndex;
3209 Index < LastIndex; Index ++) {
3210
3211 BufLen = 256;
3212 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3213 (int *)&BufLen) > 0 ||
3214 BufLen >= SK_PNMI_VPD_DATALEN) {
3215
3216 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3217 SK_PNMI_ERR022,
3218 SK_PNMI_ERR022MSG);
3219
3220 *pLen = 0;
3221 return (SK_PNMI_ERR_GENERAL);
3222 }
3223
3224 *(pBuf + Offset) = (char)BufLen;
3225 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3226 Offset += BufLen + 1;
3227 }
3228 *pLen = Offset;
3229 break;
3230
3231 case OID_SKGE_VPD_ACCESS:
3232 if (*pLen < LastIndex - FirstIndex) {
3233
3234 *pLen = LastIndex - FirstIndex;
3235 return (SK_PNMI_ERR_TOO_SHORT);
3236 }
3237
3238 for (Offset = 0, Index = FirstIndex;
3239 Index < LastIndex; Index ++) {
3240
3241 if (VpdMayWrite(KeyArr[Index])) {
3242
3243 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3244 }
3245 else {
3246 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3247 }
3248 Offset ++;
3249 }
3250 *pLen = Offset;
3251 break;
3252
3253 case OID_SKGE_VPD_ACTION:
3254 Offset = LastIndex - FirstIndex;
3255 if (*pLen < Offset) {
3256
3257 *pLen = Offset;
3258 return (SK_PNMI_ERR_TOO_SHORT);
3259 }
3260 SK_MEMSET(pBuf, 0, Offset);
3261 *pLen = Offset;
3262 break;
3263
3264 default:
3265 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3266 SK_PNMI_ERR023MSG);
3267
3268 *pLen = 0;
3269 return (SK_PNMI_ERR_GENERAL);
3270 }
3271 }
3272 else {
3273 /* The only OID which can be set is VPD_ACTION */
3274 if (Id != OID_SKGE_VPD_ACTION) {
3275
3276 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3277 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3278 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3279 Id == OID_SKGE_VPD_KEY ||
3280 Id == OID_SKGE_VPD_VALUE ||
3281 Id == OID_SKGE_VPD_ACCESS) {
3282
3283 *pLen = 0;
3284 return (SK_PNMI_ERR_READ_ONLY);
3285 }
3286
3287 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3288 SK_PNMI_ERR024MSG);
3289
3290 *pLen = 0;
3291 return (SK_PNMI_ERR_GENERAL);
3292 }
3293
3294 /*
3295 * From this point we handle VPD_ACTION. Check the buffer
3296 * length. It should at least have the size of one byte.
3297 */
3298 if (*pLen < 1) {
3299
3300 *pLen = 1;
3301 return (SK_PNMI_ERR_TOO_SHORT);
3302 }
3303
3304 /*
3305 * The first byte contains the VPD action type we should
3306 * perform.
3307 */
3308 switch (*pBuf) {
3309
3310 case SK_PNMI_VPD_IGNORE:
3311 /* Nothing to do */
3312 break;
3313
3314 case SK_PNMI_VPD_CREATE:
3315 /*
3316 * We have to create a new VPD entry or we modify
3317 * an existing one. Check first the buffer length.
3318 */
3319 if (*pLen < 4) {
3320
3321 *pLen = 4;
3322 return (SK_PNMI_ERR_TOO_SHORT);
3323 }
3324 KeyStr[0] = pBuf[1];
3325 KeyStr[1] = pBuf[2];
3326 KeyStr[2] = 0;
3327
3328 /*
3329 * Is the entry writable or does it belong to the
3330 * read-only area?
3331 */
3332 if (!VpdMayWrite(KeyStr)) {
3333
3334 *pLen = 0;
3335 return (SK_PNMI_ERR_BAD_VALUE);
3336 }
3337
3338 Offset = (int)pBuf[3] & 0xFF;
3339
3340 SK_MEMCPY(Buf, pBuf + 4, Offset);
3341 Buf[Offset] = 0;
3342
3343 /* A preset ends here */
3344 if (Action == SK_PNMI_PRESET) {
3345
3346 return (SK_PNMI_ERR_OK);
3347 }
3348
3349 /* Write the new entry or modify an existing one */
3350 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3351 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3352
3353 *pLen = 0;
3354 return (SK_PNMI_ERR_BAD_VALUE);
3355 }
3356 else if (Ret != SK_PNMI_VPD_OK) {
3357
3358 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3359 SK_PNMI_ERR025MSG);
3360
3361 *pLen = 0;
3362 return (SK_PNMI_ERR_GENERAL);
3363 }
3364
3365 /*
3366 * Perform an update of the VPD data. This is
3367 * not mandantory, but just to be sure.
3368 */
3369 Ret = VpdUpdate(pAC, IoC);
3370 if (Ret != SK_PNMI_VPD_OK) {
3371
3372 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3373 SK_PNMI_ERR026MSG);
3374
3375 *pLen = 0;
3376 return (SK_PNMI_ERR_GENERAL);
3377 }
3378 break;
3379
3380 case SK_PNMI_VPD_DELETE:
3381 /* Check if the buffer size is plausible */
3382 if (*pLen < 3) {
3383
3384 *pLen = 3;
3385 return (SK_PNMI_ERR_TOO_SHORT);
3386 }
3387 if (*pLen > 3) {
3388
3389 *pLen = 0;
3390 return (SK_PNMI_ERR_BAD_VALUE);
3391 }
3392 KeyStr[0] = pBuf[1];
3393 KeyStr[1] = pBuf[2];
3394 KeyStr[2] = 0;
3395
3396 /* Find the passed key in the array */
3397 for (Index = 0; Index < KeyNo; Index ++) {
3398
3399 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3400
3401 break;
3402 }
3403 }
3404 /*
3405 * If we cannot find the key it is wrong, so we
3406 * return an appropriate error value.
3407 */
3408 if (Index == KeyNo) {
3409
3410 *pLen = 0;
3411 return (SK_PNMI_ERR_BAD_VALUE);
3412 }
3413
3414 if (Action == SK_PNMI_PRESET) {
3415
3416 return (SK_PNMI_ERR_OK);
3417 }
3418
3419 /* Ok, you wanted it and you will get it */
3420 Ret = VpdDelete(pAC, IoC, KeyStr);
3421 if (Ret != SK_PNMI_VPD_OK) {
3422
3423 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3424 SK_PNMI_ERR027MSG);
3425
3426 *pLen = 0;
3427 return (SK_PNMI_ERR_GENERAL);
3428 }
3429
3430 /*
3431 * Perform an update of the VPD data. This is
3432 * not mandantory, but just to be sure.
3433 */
3434 Ret = VpdUpdate(pAC, IoC);
3435 if (Ret != SK_PNMI_VPD_OK) {
3436
3437 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3438 SK_PNMI_ERR028MSG);
3439
3440 *pLen = 0;
3441 return (SK_PNMI_ERR_GENERAL);
3442 }
3443 break;
3444
3445 default:
3446 *pLen = 0;
3447 return (SK_PNMI_ERR_BAD_VALUE);
3448 }
3449 }
3450
3451 return (SK_PNMI_ERR_OK);
3452}
3453
3454/*****************************************************************************
3455 *
3456 * General - OID handler function of various single instance OIDs
3457 *
3458 * Description:
3459 * The code is simple. No description necessary.
3460 *
3461 * Returns:
3462 * SK_PNMI_ERR_OK The request was successfully performed.
3463 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3464 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3465 * the correct data (e.g. a 32bit value is
3466 * needed, but a 16 bit value was passed).
3467 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3468 * exist (e.g. port instance 3 on a two port
3469 * adapter.
3470 */
3471PNMI_STATIC int General(
3472SK_AC *pAC, /* Pointer to adapter context */
3473SK_IOC IoC, /* IO context handle */
3474int Action, /* GET/PRESET/SET action */
3475SK_U32 Id, /* Object ID that is to be processed */
3476char *pBuf, /* Buffer used for the management data transfer */
3477unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3478SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3479unsigned int TableIndex, /* Index to the Id table */
3480SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3481{
3482 int Ret;
3483 unsigned int Index;
3484 unsigned int Len;
3485 unsigned int Offset;
3486 unsigned int Val;
3487 SK_U8 Val8;
3488 SK_U16 Val16;
3489 SK_U32 Val32;
3490 SK_U64 Val64;
3491 SK_U64 Val64RxHwErrs = 0;
3492 SK_U64 Val64TxHwErrs = 0;
3493 SK_BOOL Is64BitReq = SK_FALSE;
3494 char Buf[256];
3495 int MacType;
3496
3497 /*
3498 * Check instance. We only handle single instance variables.
3499 */
3500 if (Instance != (SK_U32)(-1) && Instance != 1) {
3501
3502 *pLen = 0;
3503 return (SK_PNMI_ERR_UNKNOWN_INST);
3504 }
3505
3506 /*
3507 * Check action. We only allow get requests.
3508 */
3509 if (Action != SK_PNMI_GET) {
3510
3511 *pLen = 0;
3512 return (SK_PNMI_ERR_READ_ONLY);
3513 }
3514
3515 MacType = pAC->GIni.GIMacType;
3516
3517 /*
3518 * Check length for the various supported OIDs
3519 */
3520 switch (Id) {
3521
3522 case OID_GEN_XMIT_ERROR:
3523 case OID_GEN_RCV_ERROR:
3524 case OID_GEN_RCV_NO_BUFFER:
3525#ifndef SK_NDIS_64BIT_CTR
3526 if (*pLen < sizeof(SK_U32)) {
3527 *pLen = sizeof(SK_U32);
3528 return (SK_PNMI_ERR_TOO_SHORT);
3529 }
3530
3531#else /* SK_NDIS_64BIT_CTR */
3532
3533 /*
3534 * for compatibility, at least 32bit are required for oid
3535 */
3536 if (*pLen < sizeof(SK_U32)) {
3537 /*
3538 * but indicate handling for 64bit values,
3539 * if insufficient space is provided
3540 */
3541 *pLen = sizeof(SK_U64);
3542 return (SK_PNMI_ERR_TOO_SHORT);
3543 }
3544
3545 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3546#endif /* SK_NDIS_64BIT_CTR */
3547 break;
3548
3549 case OID_SKGE_PORT_NUMBER:
3550 case OID_SKGE_DEVICE_TYPE:
3551 case OID_SKGE_RESULT:
3552 case OID_SKGE_RLMT_MONITOR_NUMBER:
3553 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3554 case OID_SKGE_TRAP_NUMBER:
3555 case OID_SKGE_MDB_VERSION:
3556 case OID_SKGE_BOARDLEVEL:
3557 case OID_SKGE_CHIPID:
3558 case OID_SKGE_RAMSIZE:
3559 if (*pLen < sizeof(SK_U32)) {
3560
3561 *pLen = sizeof(SK_U32);
3562 return (SK_PNMI_ERR_TOO_SHORT);
3563 }
3564 break;
3565
3566 case OID_SKGE_CHIPSET:
3567 if (*pLen < sizeof(SK_U16)) {
3568
3569 *pLen = sizeof(SK_U16);
3570 return (SK_PNMI_ERR_TOO_SHORT);
3571 }
3572 break;
3573
3574 case OID_SKGE_BUS_TYPE:
3575 case OID_SKGE_BUS_SPEED:
3576 case OID_SKGE_BUS_WIDTH:
3577 case OID_SKGE_SENSOR_NUMBER:
3578 case OID_SKGE_CHKSM_NUMBER:
3579 case OID_SKGE_VAUXAVAIL:
3580 if (*pLen < sizeof(SK_U8)) {
3581
3582 *pLen = sizeof(SK_U8);
3583 return (SK_PNMI_ERR_TOO_SHORT);
3584 }
3585 break;
3586
3587 case OID_SKGE_TX_SW_QUEUE_LEN:
3588 case OID_SKGE_TX_SW_QUEUE_MAX:
3589 case OID_SKGE_TX_RETRY:
3590 case OID_SKGE_RX_INTR_CTS:
3591 case OID_SKGE_TX_INTR_CTS:
3592 case OID_SKGE_RX_NO_BUF_CTS:
3593 case OID_SKGE_TX_NO_BUF_CTS:
3594 case OID_SKGE_TX_USED_DESCR_NO:
3595 case OID_SKGE_RX_DELIVERED_CTS:
3596 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3597 case OID_SKGE_RX_HW_ERROR_CTS:
3598 case OID_SKGE_TX_HW_ERROR_CTS:
3599 case OID_SKGE_IN_ERRORS_CTS:
3600 case OID_SKGE_OUT_ERROR_CTS:
3601 case OID_SKGE_ERR_RECOVERY_CTS:
3602 case OID_SKGE_SYSUPTIME:
3603 if (*pLen < sizeof(SK_U64)) {
3604
3605 *pLen = sizeof(SK_U64);
3606 return (SK_PNMI_ERR_TOO_SHORT);
3607 }
3608 break;
3609
3610 default:
3611 /* Checked later */
3612 break;
3613 }
3614
3615 /* Update statistic */
3616 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3617 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3618 Id == OID_SKGE_IN_ERRORS_CTS ||
3619 Id == OID_SKGE_OUT_ERROR_CTS ||
3620 Id == OID_GEN_XMIT_ERROR ||
3621 Id == OID_GEN_RCV_ERROR) {
3622
3623 /* Force the XMAC to update its statistic counters and
3624 * Increment semaphore to indicate that an update was
3625 * already done.
3626 */
3627 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3628 if (Ret != SK_PNMI_ERR_OK) {
3629
3630 *pLen = 0;
3631 return (Ret);
3632 }
3633 pAC->Pnmi.MacUpdatedFlag ++;
3634
3635 /*
3636 * Some OIDs consist of multiple hardware counters. Those
3637 * values which are contained in all of them will be added
3638 * now.
3639 */
3640 switch (Id) {
3641
3642 case OID_SKGE_RX_HW_ERROR_CTS:
3643 case OID_SKGE_IN_ERRORS_CTS:
3644 case OID_GEN_RCV_ERROR:
3645 Val64RxHwErrs =
3646 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3647 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3648 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3649 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3650 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3651 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3652 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3653 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3654 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3655 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3656 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3657 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3658 break;
3659
3660 case OID_SKGE_TX_HW_ERROR_CTS:
3661 case OID_SKGE_OUT_ERROR_CTS:
3662 case OID_GEN_XMIT_ERROR:
3663 Val64TxHwErrs =
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3668 break;
3669 }
3670 }
3671
3672 /*
3673 * Retrieve value
3674 */
3675 switch (Id) {
3676
3677 case OID_SKGE_SUPPORTED_LIST:
3678 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3679 if (*pLen < Len) {
3680
3681 *pLen = Len;
3682 return (SK_PNMI_ERR_TOO_SHORT);
3683 }
3684 for (Offset = 0, Index = 0; Offset < Len;
3685 Offset += sizeof(SK_U32), Index ++) {
3686
3687 Val32 = (SK_U32)IdTable[Index].Id;
3688 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3689 }
3690 *pLen = Len;
3691 break;
3692
3693 case OID_SKGE_BOARDLEVEL:
3694 Val32 = (SK_U32)pAC->GIni.GILevel;
3695 SK_PNMI_STORE_U32(pBuf, Val32);
3696 *pLen = sizeof(SK_U32);
3697 break;
3698
3699 case OID_SKGE_PORT_NUMBER:
3700 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3701 SK_PNMI_STORE_U32(pBuf, Val32);
3702 *pLen = sizeof(SK_U32);
3703 break;
3704
3705 case OID_SKGE_DEVICE_TYPE:
3706 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3707 SK_PNMI_STORE_U32(pBuf, Val32);
3708 *pLen = sizeof(SK_U32);
3709 break;
3710
3711 case OID_SKGE_DRIVER_DESCR:
3712 if (pAC->Pnmi.pDriverDescription == NULL) {
3713
3714 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3715 SK_PNMI_ERR007MSG);
3716
3717 *pLen = 0;
3718 return (SK_PNMI_ERR_GENERAL);
3719 }
3720
3721 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3722 if (Len > SK_PNMI_STRINGLEN1) {
3723
3724 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3725 SK_PNMI_ERR029MSG);
3726
3727 *pLen = 0;
3728 return (SK_PNMI_ERR_GENERAL);
3729 }
3730
3731 if (*pLen < Len) {
3732
3733 *pLen = Len;
3734 return (SK_PNMI_ERR_TOO_SHORT);
3735 }
3736 *pBuf = (char)(Len - 1);
3737 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3738 *pLen = Len;
3739 break;
3740
3741 case OID_SKGE_DRIVER_VERSION:
3742 if (pAC->Pnmi.pDriverVersion == NULL) {
3743
3744 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3745 SK_PNMI_ERR030MSG);
3746
3747 *pLen = 0;
3748 return (SK_PNMI_ERR_GENERAL);
3749 }
3750
3751 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3752 if (Len > SK_PNMI_STRINGLEN1) {
3753
3754 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3755 SK_PNMI_ERR031MSG);
3756
3757 *pLen = 0;
3758 return (SK_PNMI_ERR_GENERAL);
3759 }
3760
3761 if (*pLen < Len) {
3762
3763 *pLen = Len;
3764 return (SK_PNMI_ERR_TOO_SHORT);
3765 }
3766 *pBuf = (char)(Len - 1);
3767 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3768 *pLen = Len;
3769 break;
3770
3771 case OID_SKGE_DRIVER_RELDATE:
3772 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3773
3774 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3775 SK_PNMI_ERR053MSG);
3776
3777 *pLen = 0;
3778 return (SK_PNMI_ERR_GENERAL);
3779 }
3780
3781 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3782 if (Len > SK_PNMI_STRINGLEN1) {
3783
3784 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3785 SK_PNMI_ERR054MSG);
3786
3787 *pLen = 0;
3788 return (SK_PNMI_ERR_GENERAL);
3789 }
3790
3791 if (*pLen < Len) {
3792
3793 *pLen = Len;
3794 return (SK_PNMI_ERR_TOO_SHORT);
3795 }
3796 *pBuf = (char)(Len - 1);
3797 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3798 *pLen = Len;
3799 break;
3800
3801 case OID_SKGE_DRIVER_FILENAME:
3802 if (pAC->Pnmi.pDriverFileName == NULL) {
3803
3804 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3805 SK_PNMI_ERR055MSG);
3806
3807 *pLen = 0;
3808 return (SK_PNMI_ERR_GENERAL);
3809 }
3810
3811 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3812 if (Len > SK_PNMI_STRINGLEN1) {
3813
3814 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3815 SK_PNMI_ERR056MSG);
3816
3817 *pLen = 0;
3818 return (SK_PNMI_ERR_GENERAL);
3819 }
3820
3821 if (*pLen < Len) {
3822
3823 *pLen = Len;
3824 return (SK_PNMI_ERR_TOO_SHORT);
3825 }
3826 *pBuf = (char)(Len - 1);
3827 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3828 *pLen = Len;
3829 break;
3830
3831 case OID_SKGE_HW_DESCR:
3832 /*
3833 * The hardware description is located in the VPD. This
3834 * query may move to the initialisation routine. But
3835 * the VPD data is cached and therefore a call here
3836 * will not make much difference.
3837 */
3838 Len = 256;
3839 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3840
3841 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3842 SK_PNMI_ERR032MSG);
3843
3844 *pLen = 0;
3845 return (SK_PNMI_ERR_GENERAL);
3846 }
3847 Len ++;
3848 if (Len > SK_PNMI_STRINGLEN1) {
3849
3850 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3851 SK_PNMI_ERR033MSG);
3852
3853 *pLen = 0;
3854 return (SK_PNMI_ERR_GENERAL);
3855 }
3856 if (*pLen < Len) {
3857
3858 *pLen = Len;
3859 return (SK_PNMI_ERR_TOO_SHORT);
3860 }
3861 *pBuf = (char)(Len - 1);
3862 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3863 *pLen = Len;
3864 break;
3865
3866 case OID_SKGE_HW_VERSION:
3867 /* Oh, I love to do some string manipulation */
3868 if (*pLen < 5) {
3869
3870 *pLen = 5;
3871 return (SK_PNMI_ERR_TOO_SHORT);
3872 }
3873 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3874 pBuf[0] = 4;
3875 pBuf[1] = 'v';
3876 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3877 pBuf[3] = '.';
3878 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3879 *pLen = 5;
3880 break;
3881
3882 case OID_SKGE_CHIPSET:
3883 Val16 = pAC->Pnmi.Chipset;
3884 SK_PNMI_STORE_U16(pBuf, Val16);
3885 *pLen = sizeof(SK_U16);
3886 break;
3887
3888 case OID_SKGE_CHIPID:
3889 Val32 = pAC->GIni.GIChipId;
3890 SK_PNMI_STORE_U32(pBuf, Val32);
3891 *pLen = sizeof(SK_U32);
3892 break;
3893
3894 case OID_SKGE_RAMSIZE:
3895 Val32 = pAC->GIni.GIRamSize;
3896 SK_PNMI_STORE_U32(pBuf, Val32);
3897 *pLen = sizeof(SK_U32);
3898 break;
3899
3900 case OID_SKGE_VAUXAVAIL:
3901 *pBuf = (char) pAC->GIni.GIVauxAvail;
3902 *pLen = sizeof(char);
3903 break;
3904
3905 case OID_SKGE_BUS_TYPE:
3906 *pBuf = (char) SK_PNMI_BUS_PCI;
3907 *pLen = sizeof(char);
3908 break;
3909
3910 case OID_SKGE_BUS_SPEED:
3911 *pBuf = pAC->Pnmi.PciBusSpeed;
3912 *pLen = sizeof(char);
3913 break;
3914
3915 case OID_SKGE_BUS_WIDTH:
3916 *pBuf = pAC->Pnmi.PciBusWidth;
3917 *pLen = sizeof(char);
3918 break;
3919
3920 case OID_SKGE_RESULT:
3921 Val32 = pAC->Pnmi.TestResult;
3922 SK_PNMI_STORE_U32(pBuf, Val32);
3923 *pLen = sizeof(SK_U32);
3924 break;
3925
3926 case OID_SKGE_SENSOR_NUMBER:
3927 *pBuf = (char)pAC->I2c.MaxSens;
3928 *pLen = sizeof(char);
3929 break;
3930
3931 case OID_SKGE_CHKSM_NUMBER:
3932 *pBuf = SKCS_NUM_PROTOCOLS;
3933 *pLen = sizeof(char);
3934 break;
3935
3936 case OID_SKGE_TRAP_NUMBER:
3937 GetTrapQueueLen(pAC, &Len, &Val);
3938 Val32 = (SK_U32)Val;
3939 SK_PNMI_STORE_U32(pBuf, Val32);
3940 *pLen = sizeof(SK_U32);
3941 break;
3942
3943 case OID_SKGE_TRAP:
3944 GetTrapQueueLen(pAC, &Len, &Val);
3945 if (*pLen < Len) {
3946
3947 *pLen = Len;
3948 return (SK_PNMI_ERR_TOO_SHORT);
3949 }
3950 CopyTrapQueue(pAC, pBuf);
3951 *pLen = Len;
3952 break;
3953
3954 case OID_SKGE_RLMT_MONITOR_NUMBER:
3955/* XXX Not yet implemented by RLMT therefore we return zero elements */
3956 Val32 = 0;
3957 SK_PNMI_STORE_U32(pBuf, Val32);
3958 *pLen = sizeof(SK_U32);
3959 break;
3960
3961 case OID_SKGE_TX_SW_QUEUE_LEN:
3962 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3963 if (MacType == SK_MAC_XMAC) {
3964 /* Dual net mode */
3965 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3966 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3967 }
3968 /* Single net mode */
3969 else {
3970 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3971 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3972 }
3973 }
3974 else {
3975 /* Dual net mode */
3976 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3977 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3978 }
3979 /* Single net mode */
3980 else {
3981 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3982 pAC->Pnmi.Port[1].TxSwQueueLen;
3983 }
3984 }
3985 SK_PNMI_STORE_U64(pBuf, Val64);
3986 *pLen = sizeof(SK_U64);
3987 break;
3988
3989
3990 case OID_SKGE_TX_SW_QUEUE_MAX:
3991 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3992 if (MacType == SK_MAC_XMAC) {
3993 /* Dual net mode */
3994 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3995 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
3996 }
3997 /* Single net mode */
3998 else {
3999 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4000 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4001 }
4002 }
4003 else {
4004 /* Dual net mode */
4005 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4006 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4007 }
4008 /* Single net mode */
4009 else {
4010 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4011 pAC->Pnmi.Port[1].TxSwQueueMax;
4012 }
4013 }
4014 SK_PNMI_STORE_U64(pBuf, Val64);
4015 *pLen = sizeof(SK_U64);
4016 break;
4017
4018 case OID_SKGE_TX_RETRY:
4019 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4020 if (MacType == SK_MAC_XMAC) {
4021 /* Dual net mode */
4022 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4023 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4024 }
4025 /* Single net mode */
4026 else {
4027 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4028 pAC->Pnmi.BufPort[1].TxRetryCts;
4029 }
4030 }
4031 else {
4032 /* Dual net mode */
4033 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4034 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4035 }
4036 /* Single net mode */
4037 else {
4038 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4039 pAC->Pnmi.Port[1].TxRetryCts;
4040 }
4041 }
4042 SK_PNMI_STORE_U64(pBuf, Val64);
4043 *pLen = sizeof(SK_U64);
4044 break;
4045
4046 case OID_SKGE_RX_INTR_CTS:
4047 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4048 if (MacType == SK_MAC_XMAC) {
4049 /* Dual net mode */
4050 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4051 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4052 }
4053 /* Single net mode */
4054 else {
4055 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4056 pAC->Pnmi.BufPort[1].RxIntrCts;
4057 }
4058 }
4059 else {
4060 /* Dual net mode */
4061 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4062 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4063 }
4064 /* Single net mode */
4065 else {
4066 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4067 pAC->Pnmi.Port[1].RxIntrCts;
4068 }
4069 }
4070 SK_PNMI_STORE_U64(pBuf, Val64);
4071 *pLen = sizeof(SK_U64);
4072 break;
4073
4074 case OID_SKGE_TX_INTR_CTS:
4075 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4076 if (MacType == SK_MAC_XMAC) {
4077 /* Dual net mode */
4078 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4079 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4080 }
4081 /* Single net mode */
4082 else {
4083 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4084 pAC->Pnmi.BufPort[1].TxIntrCts;
4085 }
4086 }
4087 else {
4088 /* Dual net mode */
4089 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4090 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4091 }
4092 /* Single net mode */
4093 else {
4094 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4095 pAC->Pnmi.Port[1].TxIntrCts;
4096 }
4097 }
4098 SK_PNMI_STORE_U64(pBuf, Val64);
4099 *pLen = sizeof(SK_U64);
4100 break;
4101
4102 case OID_SKGE_RX_NO_BUF_CTS:
4103 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4104 if (MacType == SK_MAC_XMAC) {
4105 /* Dual net mode */
4106 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4107 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4108 }
4109 /* Single net mode */
4110 else {
4111 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4112 pAC->Pnmi.BufPort[1].RxNoBufCts;
4113 }
4114 }
4115 else {
4116 /* Dual net mode */
4117 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4118 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4119 }
4120 /* Single net mode */
4121 else {
4122 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4123 pAC->Pnmi.Port[1].RxNoBufCts;
4124 }
4125 }
4126 SK_PNMI_STORE_U64(pBuf, Val64);
4127 *pLen = sizeof(SK_U64);
4128 break;
4129
4130 case OID_SKGE_TX_NO_BUF_CTS:
4131 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4132 if (MacType == SK_MAC_XMAC) {
4133 /* Dual net mode */
4134 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4135 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4136 }
4137 /* Single net mode */
4138 else {
4139 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4140 pAC->Pnmi.BufPort[1].TxNoBufCts;
4141 }
4142 }
4143 else {
4144 /* Dual net mode */
4145 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4146 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4147 }
4148 /* Single net mode */
4149 else {
4150 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4151 pAC->Pnmi.Port[1].TxNoBufCts;
4152 }
4153 }
4154 SK_PNMI_STORE_U64(pBuf, Val64);
4155 *pLen = sizeof(SK_U64);
4156 break;
4157
4158 case OID_SKGE_TX_USED_DESCR_NO:
4159 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4160 if (MacType == SK_MAC_XMAC) {
4161 /* Dual net mode */
4162 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4163 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4164 }
4165 /* Single net mode */
4166 else {
4167 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4168 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4169 }
4170 }
4171 else {
4172 /* Dual net mode */
4173 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4174 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4175 }
4176 /* Single net mode */
4177 else {
4178 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4179 pAC->Pnmi.Port[1].TxUsedDescrNo;
4180 }
4181 }
4182 SK_PNMI_STORE_U64(pBuf, Val64);
4183 *pLen = sizeof(SK_U64);
4184 break;
4185
4186 case OID_SKGE_RX_DELIVERED_CTS:
4187 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4188 if (MacType == SK_MAC_XMAC) {
4189 /* Dual net mode */
4190 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4191 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4192 }
4193 /* Single net mode */
4194 else {
4195 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4196 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4197 }
4198 }
4199 else {
4200 /* Dual net mode */
4201 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4202 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4203 }
4204 /* Single net mode */
4205 else {
4206 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4207 pAC->Pnmi.Port[1].RxDeliveredCts;
4208 }
4209 }
4210 SK_PNMI_STORE_U64(pBuf, Val64);
4211 *pLen = sizeof(SK_U64);
4212 break;
4213
4214 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4215 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4216 if (MacType == SK_MAC_XMAC) {
4217 /* Dual net mode */
4218 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4219 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4220 }
4221 /* Single net mode */
4222 else {
4223 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4224 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4225 }
4226 }
4227 else {
4228 /* Dual net mode */
4229 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4230 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4231 }
4232 /* Single net mode */
4233 else {
4234 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4235 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4236 }
4237 }
4238 SK_PNMI_STORE_U64(pBuf, Val64);
4239 *pLen = sizeof(SK_U64);
4240 break;
4241
4242 case OID_SKGE_RX_HW_ERROR_CTS:
4243 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4244 *pLen = sizeof(SK_U64);
4245 break;
4246
4247 case OID_SKGE_TX_HW_ERROR_CTS:
4248 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4249 *pLen = sizeof(SK_U64);
4250 break;
4251
4252 case OID_SKGE_IN_ERRORS_CTS:
4253 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4254 if (MacType == SK_MAC_XMAC) {
4255 /* Dual net mode */
4256 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4257 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4258 }
4259 /* Single net mode */
4260 else {
4261 Val64 = Val64RxHwErrs +
4262 pAC->Pnmi.BufPort[0].RxNoBufCts +
4263 pAC->Pnmi.BufPort[1].RxNoBufCts;
4264 }
4265 }
4266 else {
4267 /* Dual net mode */
4268 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4269 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4270 }
4271 /* Single net mode */
4272 else {
4273 Val64 = Val64RxHwErrs +
4274 pAC->Pnmi.Port[0].RxNoBufCts +
4275 pAC->Pnmi.Port[1].RxNoBufCts;
4276 }
4277 }
4278 SK_PNMI_STORE_U64(pBuf, Val64);
4279 *pLen = sizeof(SK_U64);
4280 break;
4281
4282 case OID_SKGE_OUT_ERROR_CTS:
4283 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4284 if (MacType == SK_MAC_XMAC) {
4285 /* Dual net mode */
4286 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4287 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4288 }
4289 /* Single net mode */
4290 else {
4291 Val64 = Val64TxHwErrs +
4292 pAC->Pnmi.BufPort[0].TxNoBufCts +
4293 pAC->Pnmi.BufPort[1].TxNoBufCts;
4294 }
4295 }
4296 else {
4297 /* Dual net mode */
4298 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4299 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4300 }
4301 /* Single net mode */
4302 else {
4303 Val64 = Val64TxHwErrs +
4304 pAC->Pnmi.Port[0].TxNoBufCts +
4305 pAC->Pnmi.Port[1].TxNoBufCts;
4306 }
4307 }
4308 SK_PNMI_STORE_U64(pBuf, Val64);
4309 *pLen = sizeof(SK_U64);
4310 break;
4311
4312 case OID_SKGE_ERR_RECOVERY_CTS:
4313 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4314 if (MacType == SK_MAC_XMAC) {
4315 /* Dual net mode */
4316 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4317 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4318 }
4319 /* Single net mode */
4320 else {
4321 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4322 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4323 }
4324 }
4325 else {
4326 /* Dual net mode */
4327 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4328 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4329 }
4330 /* Single net mode */
4331 else {
4332 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4333 pAC->Pnmi.Port[1].ErrRecoveryCts;
4334 }
4335 }
4336 SK_PNMI_STORE_U64(pBuf, Val64);
4337 *pLen = sizeof(SK_U64);
4338 break;
4339
4340 case OID_SKGE_SYSUPTIME:
4341 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4342 Val64 -= pAC->Pnmi.StartUpTime;
4343 SK_PNMI_STORE_U64(pBuf, Val64);
4344 *pLen = sizeof(SK_U64);
4345 break;
4346
4347 case OID_SKGE_MDB_VERSION:
4348 Val32 = SK_PNMI_MDB_VERSION;
4349 SK_PNMI_STORE_U32(pBuf, Val32);
4350 *pLen = sizeof(SK_U32);
4351 break;
4352
4353 case OID_GEN_RCV_ERROR:
4354 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4355 if (MacType == SK_MAC_XMAC) {
4356 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4357 }
4358 else {
4359 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4360 }
4361
4362 /*
4363 * by default 32bit values are evaluated
4364 */
4365 if (!Is64BitReq) {
4366 Val32 = (SK_U32)Val64;
4367 SK_PNMI_STORE_U32(pBuf, Val32);
4368 *pLen = sizeof(SK_U32);
4369 }
4370 else {
4371 SK_PNMI_STORE_U64(pBuf, Val64);
4372 *pLen = sizeof(SK_U64);
4373 }
4374 break;
4375
4376 case OID_GEN_XMIT_ERROR:
4377 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4378 if (MacType == SK_MAC_XMAC) {
4379 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4380 }
4381 else {
4382 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4383 }
4384
4385 /*
4386 * by default 32bit values are evaluated
4387 */
4388 if (!Is64BitReq) {
4389 Val32 = (SK_U32)Val64;
4390 SK_PNMI_STORE_U32(pBuf, Val32);
4391 *pLen = sizeof(SK_U32);
4392 }
4393 else {
4394 SK_PNMI_STORE_U64(pBuf, Val64);
4395 *pLen = sizeof(SK_U64);
4396 }
4397 break;
4398
4399 case OID_GEN_RCV_NO_BUFFER:
4400 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4401 if (MacType == SK_MAC_XMAC) {
4402 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4403 }
4404 else {
4405 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4406 }
4407
4408 /*
4409 * by default 32bit values are evaluated
4410 */
4411 if (!Is64BitReq) {
4412 Val32 = (SK_U32)Val64;
4413 SK_PNMI_STORE_U32(pBuf, Val32);
4414 *pLen = sizeof(SK_U32);
4415 }
4416 else {
4417 SK_PNMI_STORE_U64(pBuf, Val64);
4418 *pLen = sizeof(SK_U64);
4419 }
4420 break;
4421
4422 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4423 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4424 SK_PNMI_STORE_U32(pBuf, Val32);
4425 *pLen = sizeof(SK_U32);
4426 break;
4427
4428 default:
4429 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4430 SK_PNMI_ERR034MSG);
4431
4432 *pLen = 0;
4433 return (SK_PNMI_ERR_GENERAL);
4434 }
4435
4436 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4437 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4438 Id == OID_SKGE_IN_ERRORS_CTS ||
4439 Id == OID_SKGE_OUT_ERROR_CTS ||
4440 Id == OID_GEN_XMIT_ERROR ||
4441 Id == OID_GEN_RCV_ERROR) {
4442
4443 pAC->Pnmi.MacUpdatedFlag --;
4444 }
4445
4446 return (SK_PNMI_ERR_OK);
4447}
4448
4449/*****************************************************************************
4450 *
4451 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4452 *
4453 * Description:
4454 * Get/Presets/Sets the RLMT OIDs.
4455 *
4456 * Returns:
4457 * SK_PNMI_ERR_OK The request was successfully performed.
4458 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4459 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4460 * the correct data (e.g. a 32bit value is
4461 * needed, but a 16 bit value was passed).
4462 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4463 * value range.
4464 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4465 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4466 * exist (e.g. port instance 3 on a two port
4467 * adapter.
4468 */
4469PNMI_STATIC int Rlmt(
4470SK_AC *pAC, /* Pointer to adapter context */
4471SK_IOC IoC, /* IO context handle */
4472int Action, /* GET/PRESET/SET action */
4473SK_U32 Id, /* Object ID that is to be processed */
4474char *pBuf, /* Buffer used for the management data transfer */
4475unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4476SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4477unsigned int TableIndex, /* Index to the Id table */
4478SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4479{
4480 int Ret;
4481 unsigned int PhysPortIndex;
4482 unsigned int PhysPortMax;
4483 SK_EVPARA EventParam;
4484 SK_U32 Val32;
4485 SK_U64 Val64;
4486
4487
4488 /*
4489 * Check instance. Only single instance OIDs are allowed here.
4490 */
4491 if (Instance != (SK_U32)(-1) && Instance != 1) {
4492
4493 *pLen = 0;
4494 return (SK_PNMI_ERR_UNKNOWN_INST);
4495 }
4496
4497 /*
4498 * Perform the requested action.
4499 */
4500 if (Action == SK_PNMI_GET) {
4501
4502 /*
4503 * Check if the buffer length is large enough.
4504 */
4505
4506 switch (Id) {
4507
4508 case OID_SKGE_RLMT_MODE:
4509 case OID_SKGE_RLMT_PORT_ACTIVE:
4510 case OID_SKGE_RLMT_PORT_PREFERRED:
4511 if (*pLen < sizeof(SK_U8)) {
4512
4513 *pLen = sizeof(SK_U8);
4514 return (SK_PNMI_ERR_TOO_SHORT);
4515 }
4516 break;
4517
4518 case OID_SKGE_RLMT_PORT_NUMBER:
4519 if (*pLen < sizeof(SK_U32)) {
4520
4521 *pLen = sizeof(SK_U32);
4522 return (SK_PNMI_ERR_TOO_SHORT);
4523 }
4524 break;
4525
4526 case OID_SKGE_RLMT_CHANGE_CTS:
4527 case OID_SKGE_RLMT_CHANGE_TIME:
4528 case OID_SKGE_RLMT_CHANGE_ESTIM:
4529 case OID_SKGE_RLMT_CHANGE_THRES:
4530 if (*pLen < sizeof(SK_U64)) {
4531
4532 *pLen = sizeof(SK_U64);
4533 return (SK_PNMI_ERR_TOO_SHORT);
4534 }
4535 break;
4536
4537 default:
4538 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4539 SK_PNMI_ERR035MSG);
4540
4541 *pLen = 0;
4542 return (SK_PNMI_ERR_GENERAL);
4543 }
4544
4545 /*
4546 * Update RLMT statistic and increment semaphores to indicate
4547 * that an update was already done. Maybe RLMT will hold its
4548 * statistic always up to date some time. Then we can
4549 * remove this type of call.
4550 */
4551 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4552
4553 *pLen = 0;
4554 return (Ret);
4555 }
4556 pAC->Pnmi.RlmtUpdatedFlag ++;
4557
4558 /*
4559 * Retrieve Value
4560 */
4561 switch (Id) {
4562
4563 case OID_SKGE_RLMT_MODE:
4564 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4565 *pLen = sizeof(char);
4566 break;
4567
4568 case OID_SKGE_RLMT_PORT_NUMBER:
4569 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4570 SK_PNMI_STORE_U32(pBuf, Val32);
4571 *pLen = sizeof(SK_U32);
4572 break;
4573
4574 case OID_SKGE_RLMT_PORT_ACTIVE:
4575 *pBuf = 0;
4576 /*
4577 * If multiple ports may become active this OID
4578 * doesn't make sense any more. A new variable in
4579 * the port structure should be created. However,
4580 * for this variable the first active port is
4581 * returned.
4582 */
4583 PhysPortMax = pAC->GIni.GIMacsFound;
4584
4585 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4586 PhysPortIndex ++) {
4587
4588 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4589
4590 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4591 break;
4592 }
4593 }
4594 *pLen = sizeof(char);
4595 break;
4596
4597 case OID_SKGE_RLMT_PORT_PREFERRED:
4598 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4599 *pLen = sizeof(char);
4600 break;
4601
4602 case OID_SKGE_RLMT_CHANGE_CTS:
4603 Val64 = pAC->Pnmi.RlmtChangeCts;
4604 SK_PNMI_STORE_U64(pBuf, Val64);
4605 *pLen = sizeof(SK_U64);
4606 break;
4607
4608 case OID_SKGE_RLMT_CHANGE_TIME:
4609 Val64 = pAC->Pnmi.RlmtChangeTime;
4610 SK_PNMI_STORE_U64(pBuf, Val64);
4611 *pLen = sizeof(SK_U64);
4612 break;
4613
4614 case OID_SKGE_RLMT_CHANGE_ESTIM:
4615 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4616 SK_PNMI_STORE_U64(pBuf, Val64);
4617 *pLen = sizeof(SK_U64);
4618 break;
4619
4620 case OID_SKGE_RLMT_CHANGE_THRES:
4621 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4622 SK_PNMI_STORE_U64(pBuf, Val64);
4623 *pLen = sizeof(SK_U64);
4624 break;
4625
4626 default:
4627 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4628 ("Rlmt: Unknown OID should be handled before"));
4629
4630 pAC->Pnmi.RlmtUpdatedFlag --;
4631 *pLen = 0;
4632 return (SK_PNMI_ERR_GENERAL);
4633 }
4634
4635 pAC->Pnmi.RlmtUpdatedFlag --;
4636 }
4637 else {
4638 /* Perform a preset or set */
4639 switch (Id) {
4640
4641 case OID_SKGE_RLMT_MODE:
4642 /* Check if the buffer length is plausible */
4643 if (*pLen < sizeof(char)) {
4644
4645 *pLen = sizeof(char);
4646 return (SK_PNMI_ERR_TOO_SHORT);
4647 }
4648 /* Check if the value range is correct */
4649 if (*pLen != sizeof(char) ||
4650 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4651 *(SK_U8 *)pBuf > 15) {
4652
4653 *pLen = 0;
4654 return (SK_PNMI_ERR_BAD_VALUE);
4655 }
4656 /* The preset ends here */
4657 if (Action == SK_PNMI_PRESET) {
4658
4659 *pLen = 0;
4660 return (SK_PNMI_ERR_OK);
4661 }
4662 /* Send an event to RLMT to change the mode */
4663 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4664 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4665 EventParam.Para32[1] = 0;
4666 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4667 EventParam) > 0) {
4668
4669 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4670 SK_PNMI_ERR037MSG);
4671
4672 *pLen = 0;
4673 return (SK_PNMI_ERR_GENERAL);
4674 }
4675 break;
4676
4677 case OID_SKGE_RLMT_PORT_PREFERRED:
4678 /* Check if the buffer length is plausible */
4679 if (*pLen < sizeof(char)) {
4680
4681 *pLen = sizeof(char);
4682 return (SK_PNMI_ERR_TOO_SHORT);
4683 }
4684 /* Check if the value range is correct */
4685 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4686 (SK_U8)pAC->GIni.GIMacsFound) {
4687
4688 *pLen = 0;
4689 return (SK_PNMI_ERR_BAD_VALUE);
4690 }
4691 /* The preset ends here */
4692 if (Action == SK_PNMI_PRESET) {
4693
4694 *pLen = 0;
4695 return (SK_PNMI_ERR_OK);
4696 }
4697
4698 /*
4699 * Send an event to RLMT change the preferred port.
4700 * A param of -1 means automatic mode. RLMT will
4701 * make the decision which is the preferred port.
4702 */
4703 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4704 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4705 EventParam.Para32[1] = NetIndex;
4706 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4707 EventParam) > 0) {
4708
4709 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4710 SK_PNMI_ERR038MSG);
4711
4712 *pLen = 0;
4713 return (SK_PNMI_ERR_GENERAL);
4714 }
4715 break;
4716
4717 case OID_SKGE_RLMT_CHANGE_THRES:
4718 /* Check if the buffer length is plausible */
4719 if (*pLen < sizeof(SK_U64)) {
4720
4721 *pLen = sizeof(SK_U64);
4722 return (SK_PNMI_ERR_TOO_SHORT);
4723 }
4724 /*
4725 * There are not many restrictions to the
4726 * value range.
4727 */
4728 if (*pLen != sizeof(SK_U64)) {
4729
4730 *pLen = 0;
4731 return (SK_PNMI_ERR_BAD_VALUE);
4732 }
4733 /* A preset ends here */
4734 if (Action == SK_PNMI_PRESET) {
4735
4736 *pLen = 0;
4737 return (SK_PNMI_ERR_OK);
4738 }
4739 /*
4740 * Store the new threshold, which will be taken
4741 * on the next timer event.
4742 */
4743 SK_PNMI_READ_U64(pBuf, Val64);
4744 pAC->Pnmi.RlmtChangeThreshold = Val64;
4745 break;
4746
4747 default:
4748 /* The other OIDs are not be able for set */
4749 *pLen = 0;
4750 return (SK_PNMI_ERR_READ_ONLY);
4751 }
4752 }
4753
4754 return (SK_PNMI_ERR_OK);
4755}
4756
4757/*****************************************************************************
4758 *
4759 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4760 *
4761 * Description:
4762 * Performs get requests on multiple instance variables.
4763 *
4764 * Returns:
4765 * SK_PNMI_ERR_OK The request was successfully performed.
4766 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4767 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4768 * the correct data (e.g. a 32bit value is
4769 * needed, but a 16 bit value was passed).
4770 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4771 * exist (e.g. port instance 3 on a two port
4772 * adapter.
4773 */
4774PNMI_STATIC int RlmtStat(
4775SK_AC *pAC, /* Pointer to adapter context */
4776SK_IOC IoC, /* IO context handle */
4777int Action, /* GET/PRESET/SET action */
4778SK_U32 Id, /* Object ID that is to be processed */
4779char *pBuf, /* Buffer used for the management data transfer */
4780unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4781SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4782unsigned int TableIndex, /* Index to the Id table */
4783SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4784{
4785 unsigned int PhysPortMax;
4786 unsigned int PhysPortIndex;
4787 unsigned int Limit;
4788 unsigned int Offset;
4789 int Ret;
4790 SK_U32 Val32;
4791 SK_U64 Val64;
4792
4793 /*
4794 * Calculate the port indexes from the instance.
4795 */
4796 PhysPortMax = pAC->GIni.GIMacsFound;
4797
4798 if ((Instance != (SK_U32)(-1))) {
4799 /* Check instance range */
4800 if ((Instance < 1) || (Instance > PhysPortMax)) {
4801
4802 *pLen = 0;
4803 return (SK_PNMI_ERR_UNKNOWN_INST);
4804 }
4805
4806 /* Single net mode */
4807 PhysPortIndex = Instance - 1;
4808
4809 /* Dual net mode */
4810 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4811 PhysPortIndex = NetIndex;
4812 }
4813
4814 /* Both net modes */
4815 Limit = PhysPortIndex + 1;
4816 }
4817 else {
4818 /* Single net mode */
4819 PhysPortIndex = 0;
4820 Limit = PhysPortMax;
4821
4822 /* Dual net mode */
4823 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4824 PhysPortIndex = NetIndex;
4825 Limit = PhysPortIndex + 1;
4826 }
4827 }
4828
4829 /*
4830 * Currently only get requests are allowed.
4831 */
4832 if (Action != SK_PNMI_GET) {
4833
4834 *pLen = 0;
4835 return (SK_PNMI_ERR_READ_ONLY);
4836 }
4837
4838 /*
4839 * Check if the buffer length is large enough.
4840 */
4841 switch (Id) {
4842
4843 case OID_SKGE_RLMT_PORT_INDEX:
4844 case OID_SKGE_RLMT_STATUS:
4845 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4846
4847 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4848 return (SK_PNMI_ERR_TOO_SHORT);
4849 }
4850 break;
4851
4852 case OID_SKGE_RLMT_TX_HELLO_CTS:
4853 case OID_SKGE_RLMT_RX_HELLO_CTS:
4854 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4855 case OID_SKGE_RLMT_RX_SP_CTS:
4856 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4857
4858 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4859 return (SK_PNMI_ERR_TOO_SHORT);
4860 }
4861 break;
4862
4863 default:
4864 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4865 SK_PNMI_ERR039MSG);
4866
4867 *pLen = 0;
4868 return (SK_PNMI_ERR_GENERAL);
4869
4870 }
4871
4872 /*
4873 * Update statistic and increment semaphores to indicate that
4874 * an update was already done.
4875 */
4876 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4877
4878 *pLen = 0;
4879 return (Ret);
4880 }
4881 pAC->Pnmi.RlmtUpdatedFlag ++;
4882
4883 /*
4884 * Get value
4885 */
4886 Offset = 0;
4887 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4888
4889 switch (Id) {
4890
4891 case OID_SKGE_RLMT_PORT_INDEX:
4892 Val32 = PhysPortIndex;
4893 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4894 Offset += sizeof(SK_U32);
4895 break;
4896
4897 case OID_SKGE_RLMT_STATUS:
4898 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4899 SK_RLMT_PS_INIT ||
4900 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4901 SK_RLMT_PS_DOWN) {
4902
4903 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4904 }
4905 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4906
4907 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4908 }
4909 else {
4910 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4911 }
4912 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4913 Offset += sizeof(SK_U32);
4914 break;
4915
4916 case OID_SKGE_RLMT_TX_HELLO_CTS:
4917 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4918 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4919 Offset += sizeof(SK_U64);
4920 break;
4921
4922 case OID_SKGE_RLMT_RX_HELLO_CTS:
4923 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4924 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4925 Offset += sizeof(SK_U64);
4926 break;
4927
4928 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4929 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4930 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4931 Offset += sizeof(SK_U64);
4932 break;
4933
4934 case OID_SKGE_RLMT_RX_SP_CTS:
4935 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4936 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4937 Offset += sizeof(SK_U64);
4938 break;
4939
4940 default:
4941 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4942 ("RlmtStat: Unknown OID should be errored before"));
4943
4944 pAC->Pnmi.RlmtUpdatedFlag --;
4945 *pLen = 0;
4946 return (SK_PNMI_ERR_GENERAL);
4947 }
4948 }
4949 *pLen = Offset;
4950
4951 pAC->Pnmi.RlmtUpdatedFlag --;
4952
4953 return (SK_PNMI_ERR_OK);
4954}
4955
4956/*****************************************************************************
4957 *
4958 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4959 *
4960 * Description:
4961 * Get/Presets/Sets the OIDs concerning the configuration.
4962 *
4963 * Returns:
4964 * SK_PNMI_ERR_OK The request was successfully performed.
4965 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4966 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4967 * the correct data (e.g. a 32bit value is
4968 * needed, but a 16 bit value was passed).
4969 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4970 * value range.
4971 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4972 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4973 * exist (e.g. port instance 3 on a two port
4974 * adapter.
4975 */
4976PNMI_STATIC int MacPrivateConf(
4977SK_AC *pAC, /* Pointer to adapter context */
4978SK_IOC IoC, /* IO context handle */
4979int Action, /* GET/PRESET/SET action */
4980SK_U32 Id, /* Object ID that is to be processed */
4981char *pBuf, /* Buffer used for the management data transfer */
4982unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4983SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4984unsigned int TableIndex, /* Index to the Id table */
4985SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4986{
4987 unsigned int PhysPortMax;
4988 unsigned int PhysPortIndex;
4989 unsigned int LogPortMax;
4990 unsigned int LogPortIndex;
4991 unsigned int Limit;
4992 unsigned int Offset;
4993 char Val8;
4994 char *pBufPtr;
4995 int Ret;
4996 SK_EVPARA EventParam;
4997 SK_U32 Val32;
4998
4999 /*
5000 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5001 */
5002 PhysPortMax = pAC->GIni.GIMacsFound;
5003 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5004
5005 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5006 LogPortMax--;
5007 }
5008
5009 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5010 /* Check instance range */
5011 if ((Instance < 1) || (Instance > LogPortMax)) {
5012
5013 *pLen = 0;
5014 return (SK_PNMI_ERR_UNKNOWN_INST);
5015 }
5016 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5017 Limit = LogPortIndex + 1;
5018 }
5019
5020 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5021
5022 LogPortIndex = 0;
5023 Limit = LogPortMax;
5024 }
5025
5026 /*
5027 * Perform action
5028 */
5029 if (Action == SK_PNMI_GET) {
5030
5031 /* Check length */
5032 switch (Id) {
5033
5034 case OID_SKGE_PMD:
5035 case OID_SKGE_CONNECTOR:
5036 case OID_SKGE_LINK_CAP:
5037 case OID_SKGE_LINK_MODE:
5038 case OID_SKGE_LINK_MODE_STATUS:
5039 case OID_SKGE_LINK_STATUS:
5040 case OID_SKGE_FLOWCTRL_CAP:
5041 case OID_SKGE_FLOWCTRL_MODE:
5042 case OID_SKGE_FLOWCTRL_STATUS:
5043 case OID_SKGE_PHY_OPERATION_CAP:
5044 case OID_SKGE_PHY_OPERATION_MODE:
5045 case OID_SKGE_PHY_OPERATION_STATUS:
5046 case OID_SKGE_SPEED_CAP:
5047 case OID_SKGE_SPEED_MODE:
5048 case OID_SKGE_SPEED_STATUS:
5049 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5050
5051 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5052 return (SK_PNMI_ERR_TOO_SHORT);
5053 }
5054 break;
5055
5056 case OID_SKGE_MTU:
5057 case OID_SKGE_PHY_TYPE:
5058 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5059
5060 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5061 return (SK_PNMI_ERR_TOO_SHORT);
5062 }
5063 break;
5064
5065 default:
5066 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5067 SK_PNMI_ERR041MSG);
5068 *pLen = 0;
5069 return (SK_PNMI_ERR_GENERAL);
5070 }
5071
5072 /*
5073 * Update statistic and increment semaphore to indicate
5074 * that an update was already done.
5075 */
5076 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5077
5078 *pLen = 0;
5079 return (Ret);
5080 }
5081 pAC->Pnmi.SirqUpdatedFlag ++;
5082
5083 /*
5084 * Get value
5085 */
5086 Offset = 0;
5087 for (; LogPortIndex < Limit; LogPortIndex ++) {
5088
5089 pBufPtr = pBuf + Offset;
5090
5091 switch (Id) {
5092
5093 case OID_SKGE_PMD:
5094 *pBufPtr = pAC->Pnmi.PMD;
5095 Offset += sizeof(char);
5096 break;
5097
5098 case OID_SKGE_CONNECTOR:
5099 *pBufPtr = pAC->Pnmi.Connector;
5100 Offset += sizeof(char);
5101 break;
5102
5103 case OID_SKGE_PHY_TYPE:
5104 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5105 if (LogPortIndex == 0) {
5106 continue;
5107 }
5108 else {
5109 /* Get value for physical ports */
5110 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5111 pAC, LogPortIndex);
5112 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5113 SK_PNMI_STORE_U32(pBufPtr, Val32);
5114 }
5115 }
5116 else { /* DualNetMode */
5117
5118 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5119 SK_PNMI_STORE_U32(pBufPtr, Val32);
5120 }
5121 Offset += sizeof(SK_U32);
5122 break;
5123
5124 case OID_SKGE_LINK_CAP:
5125 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5126 if (LogPortIndex == 0) {
5127 /* Get value for virtual port */
5128 VirtualConf(pAC, IoC, Id, pBufPtr);
5129 }
5130 else {
5131 /* Get value for physical ports */
5132 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5133 pAC, LogPortIndex);
5134
5135 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5136 }
5137 }
5138 else { /* DualNetMode */
5139
5140 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5141 }
5142 Offset += sizeof(char);
5143 break;
5144
5145 case OID_SKGE_LINK_MODE:
5146 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5147 if (LogPortIndex == 0) {
5148 /* Get value for virtual port */
5149 VirtualConf(pAC, IoC, Id, pBufPtr);
5150 }
5151 else {
5152 /* Get value for physical ports */
5153 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5154 pAC, LogPortIndex);
5155
5156 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5157 }
5158 }
5159 else { /* DualNetMode */
5160
5161 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5162 }
5163 Offset += sizeof(char);
5164 break;
5165
5166 case OID_SKGE_LINK_MODE_STATUS:
5167 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5168 if (LogPortIndex == 0) {
5169 /* Get value for virtual port */
5170 VirtualConf(pAC, IoC, Id, pBufPtr);
5171 }
5172 else {
5173 /* Get value for physical port */
5174 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5175 pAC, LogPortIndex);
5176
5177 *pBufPtr =
5178 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5179 }
5180 }
5181 else { /* DualNetMode */
5182
5183 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5184 }
5185 Offset += sizeof(char);
5186 break;
5187
5188 case OID_SKGE_LINK_STATUS:
5189 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5190 if (LogPortIndex == 0) {
5191 /* Get value for virtual port */
5192 VirtualConf(pAC, IoC, Id, pBufPtr);
5193 }
5194 else {
5195 /* Get value for physical ports */
5196 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5197 pAC, LogPortIndex);
5198
5199 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5200 }
5201 }
5202 else { /* DualNetMode */
5203
5204 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5205 }
5206 Offset += sizeof(char);
5207 break;
5208
5209 case OID_SKGE_FLOWCTRL_CAP:
5210 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5211 if (LogPortIndex == 0) {
5212 /* Get value for virtual port */
5213 VirtualConf(pAC, IoC, Id, pBufPtr);
5214 }
5215 else {
5216 /* Get value for physical ports */
5217 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5218 pAC, LogPortIndex);
5219
5220 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5221 }
5222 }
5223 else { /* DualNetMode */
5224
5225 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5226 }
5227 Offset += sizeof(char);
5228 break;
5229
5230 case OID_SKGE_FLOWCTRL_MODE:
5231 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5232 if (LogPortIndex == 0) {
5233 /* Get value for virtual port */
5234 VirtualConf(pAC, IoC, Id, pBufPtr);
5235 }
5236 else {
5237 /* Get value for physical port */
5238 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5239 pAC, LogPortIndex);
5240
5241 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5242 }
5243 }
5244 else { /* DualNetMode */
5245
5246 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5247 }
5248 Offset += sizeof(char);
5249 break;
5250
5251 case OID_SKGE_FLOWCTRL_STATUS:
5252 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5253 if (LogPortIndex == 0) {
5254 /* Get value for virtual port */
5255 VirtualConf(pAC, IoC, Id, pBufPtr);
5256 }
5257 else {
5258 /* Get value for physical port */
5259 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5260 pAC, LogPortIndex);
5261
5262 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5263 }
5264 }
5265 else { /* DualNetMode */
5266
5267 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5268 }
5269 Offset += sizeof(char);
5270 break;
5271
5272 case OID_SKGE_PHY_OPERATION_CAP:
5273 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5274 if (LogPortIndex == 0) {
5275 /* Get value for virtual port */
5276 VirtualConf(pAC, IoC, Id, pBufPtr);
5277 }
5278 else {
5279 /* Get value for physical ports */
5280 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5281 pAC, LogPortIndex);
5282
5283 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5284 }
5285 }
5286 else { /* DualNetMode */
5287
5288 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5289 }
5290 Offset += sizeof(char);
5291 break;
5292
5293 case OID_SKGE_PHY_OPERATION_MODE:
5294 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5295 if (LogPortIndex == 0) {
5296 /* Get value for virtual port */
5297 VirtualConf(pAC, IoC, Id, pBufPtr);
5298 }
5299 else {
5300 /* Get value for physical port */
5301 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5302 pAC, LogPortIndex);
5303
5304 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5305 }
5306 }
5307 else { /* DualNetMode */
5308
5309 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5310 }
5311 Offset += sizeof(char);
5312 break;
5313
5314 case OID_SKGE_PHY_OPERATION_STATUS:
5315 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5316 if (LogPortIndex == 0) {
5317 /* Get value for virtual port */
5318 VirtualConf(pAC, IoC, Id, pBufPtr);
5319 }
5320 else {
5321 /* Get value for physical port */
5322 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5323 pAC, LogPortIndex);
5324
5325 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5326 }
5327 }
5328 else {
5329
5330 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5331 }
5332 Offset += sizeof(char);
5333 break;
5334
5335 case OID_SKGE_SPEED_CAP:
5336 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5337 if (LogPortIndex == 0) {
5338 /* Get value for virtual port */
5339 VirtualConf(pAC, IoC, Id, pBufPtr);
5340 }
5341 else {
5342 /* Get value for physical ports */
5343 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5344 pAC, LogPortIndex);
5345
5346 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5347 }
5348 }
5349 else { /* DualNetMode */
5350
5351 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5352 }
5353 Offset += sizeof(char);
5354 break;
5355
5356 case OID_SKGE_SPEED_MODE:
5357 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5358 if (LogPortIndex == 0) {
5359 /* Get value for virtual port */
5360 VirtualConf(pAC, IoC, Id, pBufPtr);
5361 }
5362 else {
5363 /* Get value for physical port */
5364 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5365 pAC, LogPortIndex);
5366
5367 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5368 }
5369 }
5370 else { /* DualNetMode */
5371
5372 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5373 }
5374 Offset += sizeof(char);
5375 break;
5376
5377 case OID_SKGE_SPEED_STATUS:
5378 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5379 if (LogPortIndex == 0) {
5380 /* Get value for virtual port */
5381 VirtualConf(pAC, IoC, Id, pBufPtr);
5382 }
5383 else {
5384 /* Get value for physical port */
5385 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5386 pAC, LogPortIndex);
5387
5388 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5389 }
5390 }
5391 else { /* DualNetMode */
5392
5393 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5394 }
5395 Offset += sizeof(char);
5396 break;
5397
5398 case OID_SKGE_MTU:
5399 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5400 SK_PNMI_STORE_U32(pBufPtr, Val32);
5401 Offset += sizeof(SK_U32);
5402 break;
5403
5404 default:
5405 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5406 ("MacPrivateConf: Unknown OID should be handled before"));
5407
5408 pAC->Pnmi.SirqUpdatedFlag --;
5409 return (SK_PNMI_ERR_GENERAL);
5410 }
5411 }
5412 *pLen = Offset;
5413 pAC->Pnmi.SirqUpdatedFlag --;
5414
5415 return (SK_PNMI_ERR_OK);
5416 }
5417
5418 /*
5419 * From here SET or PRESET action. Check if the passed
5420 * buffer length is plausible.
5421 */
5422 switch (Id) {
5423
5424 case OID_SKGE_LINK_MODE:
5425 case OID_SKGE_FLOWCTRL_MODE:
5426 case OID_SKGE_PHY_OPERATION_MODE:
5427 case OID_SKGE_SPEED_MODE:
5428 if (*pLen < Limit - LogPortIndex) {
5429
5430 *pLen = Limit - LogPortIndex;
5431 return (SK_PNMI_ERR_TOO_SHORT);
5432 }
5433 if (*pLen != Limit - LogPortIndex) {
5434
5435 *pLen = 0;
5436 return (SK_PNMI_ERR_BAD_VALUE);
5437 }
5438 break;
5439
5440 case OID_SKGE_MTU:
5441 if (*pLen < sizeof(SK_U32)) {
5442
5443 *pLen = sizeof(SK_U32);
5444 return (SK_PNMI_ERR_TOO_SHORT);
5445 }
5446 if (*pLen != sizeof(SK_U32)) {
5447
5448 *pLen = 0;
5449 return (SK_PNMI_ERR_BAD_VALUE);
5450 }
5451 break;
5452
5453 default:
5454 *pLen = 0;
5455 return (SK_PNMI_ERR_READ_ONLY);
5456 }
5457
5458 /*
5459 * Perform preset or set
5460 */
5461 Offset = 0;
5462 for (; LogPortIndex < Limit; LogPortIndex ++) {
5463
5464 switch (Id) {
5465
5466 case OID_SKGE_LINK_MODE:
5467 /* Check the value range */
5468 Val8 = *(pBuf + Offset);
5469 if (Val8 == 0) {
5470
5471 Offset += sizeof(char);
5472 break;
5473 }
5474 if (Val8 < SK_LMODE_HALF ||
5475 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5476 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5477
5478 *pLen = 0;
5479 return (SK_PNMI_ERR_BAD_VALUE);
5480 }
5481
5482 /* The preset ends here */
5483 if (Action == SK_PNMI_PRESET) {
5484
5485 return (SK_PNMI_ERR_OK);
5486 }
5487
5488 if (LogPortIndex == 0) {
5489
5490 /*
5491 * The virtual port consists of all currently
5492 * active ports. Find them and send an event
5493 * with the new link mode to SIRQ.
5494 */
5495 for (PhysPortIndex = 0;
5496 PhysPortIndex < PhysPortMax;
5497 PhysPortIndex ++) {
5498
5499 if (!pAC->Pnmi.Port[PhysPortIndex].
5500 ActiveFlag) {
5501
5502 continue;
5503 }
5504
5505 EventParam.Para32[0] = PhysPortIndex;
5506 EventParam.Para32[1] = (SK_U32)Val8;
5507 if (SkGeSirqEvent(pAC, IoC,
5508 SK_HWEV_SET_LMODE,
5509 EventParam) > 0) {
5510
5511 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5512 SK_PNMI_ERR043,
5513 SK_PNMI_ERR043MSG);
5514
5515 *pLen = 0;
5516 return (SK_PNMI_ERR_GENERAL);
5517 }
5518 }
5519 }
5520 else {
5521 /*
5522 * Send an event with the new link mode to
5523 * the SIRQ module.
5524 */
5525 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5526 pAC, LogPortIndex);
5527 EventParam.Para32[1] = (SK_U32)Val8;
5528 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5529 EventParam) > 0) {
5530
5531 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5532 SK_PNMI_ERR043,
5533 SK_PNMI_ERR043MSG);
5534
5535 *pLen = 0;
5536 return (SK_PNMI_ERR_GENERAL);
5537 }
5538 }
5539 Offset += sizeof(char);
5540 break;
5541
5542 case OID_SKGE_FLOWCTRL_MODE:
5543 /* Check the value range */
5544 Val8 = *(pBuf + Offset);
5545 if (Val8 == 0) {
5546
5547 Offset += sizeof(char);
5548 break;
5549 }
5550 if (Val8 < SK_FLOW_MODE_NONE ||
5551 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5552 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5553
5554 *pLen = 0;
5555 return (SK_PNMI_ERR_BAD_VALUE);
5556 }
5557
5558 /* The preset ends here */
5559 if (Action == SK_PNMI_PRESET) {
5560
5561 return (SK_PNMI_ERR_OK);
5562 }
5563
5564 if (LogPortIndex == 0) {
5565
5566 /*
5567 * The virtual port consists of all currently
5568 * active ports. Find them and send an event
5569 * with the new flow control mode to SIRQ.
5570 */
5571 for (PhysPortIndex = 0;
5572 PhysPortIndex < PhysPortMax;
5573 PhysPortIndex ++) {
5574
5575 if (!pAC->Pnmi.Port[PhysPortIndex].
5576 ActiveFlag) {
5577
5578 continue;
5579 }
5580
5581 EventParam.Para32[0] = PhysPortIndex;
5582 EventParam.Para32[1] = (SK_U32)Val8;
5583 if (SkGeSirqEvent(pAC, IoC,
5584 SK_HWEV_SET_FLOWMODE,
5585 EventParam) > 0) {
5586
5587 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5588 SK_PNMI_ERR044,
5589 SK_PNMI_ERR044MSG);
5590
5591 *pLen = 0;
5592 return (SK_PNMI_ERR_GENERAL);
5593 }
5594 }
5595 }
5596 else {
5597 /*
5598 * Send an event with the new flow control
5599 * mode to the SIRQ module.
5600 */
5601 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5602 pAC, LogPortIndex);
5603 EventParam.Para32[1] = (SK_U32)Val8;
5604 if (SkGeSirqEvent(pAC, IoC,
5605 SK_HWEV_SET_FLOWMODE, EventParam)
5606 > 0) {
5607
5608 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5609 SK_PNMI_ERR044,
5610 SK_PNMI_ERR044MSG);
5611
5612 *pLen = 0;
5613 return (SK_PNMI_ERR_GENERAL);
5614 }
5615 }
5616 Offset += sizeof(char);
5617 break;
5618
5619 case OID_SKGE_PHY_OPERATION_MODE :
5620 /* Check the value range */
5621 Val8 = *(pBuf + Offset);
5622 if (Val8 == 0) {
5623 /* mode of this port remains unchanged */
5624 Offset += sizeof(char);
5625 break;
5626 }
5627 if (Val8 < SK_MS_MODE_AUTO ||
5628 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5629 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5630
5631 *pLen = 0;
5632 return (SK_PNMI_ERR_BAD_VALUE);
5633 }
5634
5635 /* The preset ends here */
5636 if (Action == SK_PNMI_PRESET) {
5637
5638 return (SK_PNMI_ERR_OK);
5639 }
5640
5641 if (LogPortIndex == 0) {
5642
5643 /*
5644 * The virtual port consists of all currently
5645 * active ports. Find them and send an event
5646 * with new master/slave (role) mode to SIRQ.
5647 */
5648 for (PhysPortIndex = 0;
5649 PhysPortIndex < PhysPortMax;
5650 PhysPortIndex ++) {
5651
5652 if (!pAC->Pnmi.Port[PhysPortIndex].
5653 ActiveFlag) {
5654
5655 continue;
5656 }
5657
5658 EventParam.Para32[0] = PhysPortIndex;
5659 EventParam.Para32[1] = (SK_U32)Val8;
5660 if (SkGeSirqEvent(pAC, IoC,
5661 SK_HWEV_SET_ROLE,
5662 EventParam) > 0) {
5663
5664 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5665 SK_PNMI_ERR042,
5666 SK_PNMI_ERR042MSG);
5667
5668 *pLen = 0;
5669 return (SK_PNMI_ERR_GENERAL);
5670 }
5671 }
5672 }
5673 else {
5674 /*
5675 * Send an event with the new master/slave
5676 * (role) mode to the SIRQ module.
5677 */
5678 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5679 pAC, LogPortIndex);
5680 EventParam.Para32[1] = (SK_U32)Val8;
5681 if (SkGeSirqEvent(pAC, IoC,
5682 SK_HWEV_SET_ROLE, EventParam) > 0) {
5683
5684 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5685 SK_PNMI_ERR042,
5686 SK_PNMI_ERR042MSG);
5687
5688 *pLen = 0;
5689 return (SK_PNMI_ERR_GENERAL);
5690 }
5691 }
5692
5693 Offset += sizeof(char);
5694 break;
5695
5696 case OID_SKGE_SPEED_MODE:
5697 /* Check the value range */
5698 Val8 = *(pBuf + Offset);
5699 if (Val8 == 0) {
5700
5701 Offset += sizeof(char);
5702 break;
5703 }
5704 if (Val8 < (SK_LSPEED_AUTO) ||
5705 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5706 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5707
5708 *pLen = 0;
5709 return (SK_PNMI_ERR_BAD_VALUE);
5710 }
5711
5712 /* The preset ends here */
5713 if (Action == SK_PNMI_PRESET) {
5714
5715 return (SK_PNMI_ERR_OK);
5716 }
5717
5718 if (LogPortIndex == 0) {
5719
5720 /*
5721 * The virtual port consists of all currently
5722 * active ports. Find them and send an event
5723 * with the new flow control mode to SIRQ.
5724 */
5725 for (PhysPortIndex = 0;
5726 PhysPortIndex < PhysPortMax;
5727 PhysPortIndex ++) {
5728
5729 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5730
5731 continue;
5732 }
5733
5734 EventParam.Para32[0] = PhysPortIndex;
5735 EventParam.Para32[1] = (SK_U32)Val8;
5736 if (SkGeSirqEvent(pAC, IoC,
5737 SK_HWEV_SET_SPEED,
5738 EventParam) > 0) {
5739
5740 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5741 SK_PNMI_ERR045,
5742 SK_PNMI_ERR045MSG);
5743
5744 *pLen = 0;
5745 return (SK_PNMI_ERR_GENERAL);
5746 }
5747 }
5748 }
5749 else {
5750 /*
5751 * Send an event with the new flow control
5752 * mode to the SIRQ module.
5753 */
5754 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5755 pAC, LogPortIndex);
5756 EventParam.Para32[1] = (SK_U32)Val8;
5757 if (SkGeSirqEvent(pAC, IoC,
5758 SK_HWEV_SET_SPEED,
5759 EventParam) > 0) {
5760
5761 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5762 SK_PNMI_ERR045,
5763 SK_PNMI_ERR045MSG);
5764
5765 *pLen = 0;
5766 return (SK_PNMI_ERR_GENERAL);
5767 }
5768 }
5769 Offset += sizeof(char);
5770 break;
5771
5772 case OID_SKGE_MTU :
5773 /* Check the value range */
5774 Val32 = *(SK_U32*)(pBuf + Offset);
5775 if (Val32 == 0) {
5776 /* mtu of this port remains unchanged */
5777 Offset += sizeof(SK_U32);
5778 break;
5779 }
5780 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5781 *pLen = 0;
5782 return (SK_PNMI_ERR_BAD_VALUE);
5783 }
5784
5785 /* The preset ends here */
5786 if (Action == SK_PNMI_PRESET) {
5787 return (SK_PNMI_ERR_OK);
5788 }
5789
5790 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5791 return (SK_PNMI_ERR_GENERAL);
5792 }
5793
5794 Offset += sizeof(SK_U32);
5795 break;
5796
5797 default:
5798 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5799 ("MacPrivateConf: Unknown OID should be handled before set"));
5800
5801 *pLen = 0;
5802 return (SK_PNMI_ERR_GENERAL);
5803 }
5804 }
5805
5806 return (SK_PNMI_ERR_OK);
5807}
5808
5809/*****************************************************************************
5810 *
5811 * Monitor - OID handler function for RLMT_MONITOR_XXX
5812 *
5813 * Description:
5814 * Because RLMT currently does not support the monitoring of
5815 * remote adapter cards, we return always an empty table.
5816 *
5817 * Returns:
5818 * SK_PNMI_ERR_OK The request was successfully performed.
5819 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5820 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5821 * the correct data (e.g. a 32bit value is
5822 * needed, but a 16 bit value was passed).
5823 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5824 * value range.
5825 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5826 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5827 * exist (e.g. port instance 3 on a two port
5828 * adapter.
5829 */
5830PNMI_STATIC int Monitor(
5831SK_AC *pAC, /* Pointer to adapter context */
5832SK_IOC IoC, /* IO context handle */
5833int Action, /* GET/PRESET/SET action */
5834SK_U32 Id, /* Object ID that is to be processed */
5835char *pBuf, /* Buffer used for the management data transfer */
5836unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5837SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5838unsigned int TableIndex, /* Index to the Id table */
5839SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5840{
5841 unsigned int Index;
5842 unsigned int Limit;
5843 unsigned int Offset;
5844 unsigned int Entries;
5845
5846
5847 /*
5848 * Calculate instance if wished.
5849 */
5850 /* XXX Not yet implemented. Return always an empty table. */
5851 Entries = 0;
5852
5853 if ((Instance != (SK_U32)(-1))) {
5854
5855 if ((Instance < 1) || (Instance > Entries)) {
5856
5857 *pLen = 0;
5858 return (SK_PNMI_ERR_UNKNOWN_INST);
5859 }
5860
5861 Index = (unsigned int)Instance - 1;
5862 Limit = (unsigned int)Instance;
5863 }
5864 else {
5865 Index = 0;
5866 Limit = Entries;
5867 }
5868
5869 /*
5870 * Get/Set value
5871 */
5872 if (Action == SK_PNMI_GET) {
5873
5874 for (Offset=0; Index < Limit; Index ++) {
5875
5876 switch (Id) {
5877
5878 case OID_SKGE_RLMT_MONITOR_INDEX:
5879 case OID_SKGE_RLMT_MONITOR_ADDR:
5880 case OID_SKGE_RLMT_MONITOR_ERRS:
5881 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
5882 case OID_SKGE_RLMT_MONITOR_ADMIN:
5883 break;
5884
5885 default:
5886 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
5887 SK_PNMI_ERR046MSG);
5888
5889 *pLen = 0;
5890 return (SK_PNMI_ERR_GENERAL);
5891 }
5892 }
5893 *pLen = Offset;
5894 }
5895 else {
5896 /* Only MONITOR_ADMIN can be set */
5897 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
5898
5899 *pLen = 0;
5900 return (SK_PNMI_ERR_READ_ONLY);
5901 }
5902
5903 /* Check if the length is plausible */
5904 if (*pLen < (Limit - Index)) {
5905
5906 return (SK_PNMI_ERR_TOO_SHORT);
5907 }
5908 /* Okay, we have a wide value range */
5909 if (*pLen != (Limit - Index)) {
5910
5911 *pLen = 0;
5912 return (SK_PNMI_ERR_BAD_VALUE);
5913 }
5914/*
5915 for (Offset=0; Index < Limit; Index ++) {
5916 }
5917*/
5918/*
5919 * XXX Not yet implemented. Return always BAD_VALUE, because the table
5920 * is empty.
5921 */
5922 *pLen = 0;
5923 return (SK_PNMI_ERR_BAD_VALUE);
5924 }
5925
5926 return (SK_PNMI_ERR_OK);
5927}
5928
5929/*****************************************************************************
5930 *
5931 * VirtualConf - Calculates the values of configuration OIDs for virtual port
5932 *
5933 * Description:
5934 * We handle here the get of the configuration group OIDs, which are
5935 * a little bit complicated. The virtual port consists of all currently
5936 * active physical ports. If multiple ports are active and configured
5937 * differently we get in some trouble to return a single value. So we
5938 * get the value of the first active port and compare it with that of
5939 * the other active ports. If they are not the same, we return a value
5940 * that indicates that the state is indeterminated.
5941 *
5942 * Returns:
5943 * Nothing
5944 */
5945PNMI_STATIC void VirtualConf(
5946SK_AC *pAC, /* Pointer to adapter context */
5947SK_IOC IoC, /* IO context handle */
5948SK_U32 Id, /* Object ID that is to be processed */
5949char *pBuf) /* Buffer used for the management data transfer */
5950{
5951 unsigned int PhysPortMax;
5952 unsigned int PhysPortIndex;
5953 SK_U8 Val8;
5954 SK_U32 Val32;
5955 SK_BOOL PortActiveFlag;
5956 SK_GEPORT *pPrt;
5957
5958 *pBuf = 0;
5959 PortActiveFlag = SK_FALSE;
5960 PhysPortMax = pAC->GIni.GIMacsFound;
5961
5962 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
5963 PhysPortIndex ++) {
5964
5965 pPrt = &pAC->GIni.GP[PhysPortIndex];
5966
5967 /* Check if the physical port is active */
5968 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5969
5970 continue;
5971 }
5972
5973 PortActiveFlag = SK_TRUE;
5974
5975 switch (Id) {
5976
5977 case OID_SKGE_PHY_TYPE:
5978 /* Check if it is the first active port */
5979 if (*pBuf == 0) {
5980 Val32 = pPrt->PhyType;
5981 SK_PNMI_STORE_U32(pBuf, Val32);
5982 continue;
5983 }
5984
5985 case OID_SKGE_LINK_CAP:
5986
5987 /*
5988 * Different capabilities should not happen, but
5989 * in the case of the cases OR them all together.
5990 * From a curious point of view the virtual port
5991 * is capable of all found capabilities.
5992 */
5993 *pBuf |= pPrt->PLinkCap;
5994 break;
5995
5996 case OID_SKGE_LINK_MODE:
5997 /* Check if it is the first active port */
5998 if (*pBuf == 0) {
5999
6000 *pBuf = pPrt->PLinkModeConf;
6001 continue;
6002 }
6003
6004 /*
6005 * If we find an active port with a different link
6006 * mode than the first one we return a value that
6007 * indicates that the link mode is indeterminated.
6008 */
6009 if (*pBuf != pPrt->PLinkModeConf) {
6010
6011 *pBuf = SK_LMODE_INDETERMINATED;
6012 }
6013 break;
6014
6015 case OID_SKGE_LINK_MODE_STATUS:
6016 /* Get the link mode of the physical port */
6017 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6018
6019 /* Check if it is the first active port */
6020 if (*pBuf == 0) {
6021
6022 *pBuf = Val8;
6023 continue;
6024 }
6025
6026 /*
6027 * If we find an active port with a different link
6028 * mode status than the first one we return a value
6029 * that indicates that the link mode status is
6030 * indeterminated.
6031 */
6032 if (*pBuf != Val8) {
6033
6034 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6035 }
6036 break;
6037
6038 case OID_SKGE_LINK_STATUS:
6039 /* Get the link status of the physical port */
6040 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6041
6042 /* Check if it is the first active port */
6043 if (*pBuf == 0) {
6044
6045 *pBuf = Val8;
6046 continue;
6047 }
6048
6049 /*
6050 * If we find an active port with a different link
6051 * status than the first one, we return a value
6052 * that indicates that the link status is
6053 * indeterminated.
6054 */
6055 if (*pBuf != Val8) {
6056
6057 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6058 }
6059 break;
6060
6061 case OID_SKGE_FLOWCTRL_CAP:
6062 /* Check if it is the first active port */
6063 if (*pBuf == 0) {
6064
6065 *pBuf = pPrt->PFlowCtrlCap;
6066 continue;
6067 }
6068
6069 /*
6070 * From a curious point of view the virtual port
6071 * is capable of all found capabilities.
6072 */
6073 *pBuf |= pPrt->PFlowCtrlCap;
6074 break;
6075
6076 case OID_SKGE_FLOWCTRL_MODE:
6077 /* Check if it is the first active port */
6078 if (*pBuf == 0) {
6079
6080 *pBuf = pPrt->PFlowCtrlMode;
6081 continue;
6082 }
6083
6084 /*
6085 * If we find an active port with a different flow
6086 * control mode than the first one, we return a value
6087 * that indicates that the mode is indeterminated.
6088 */
6089 if (*pBuf != pPrt->PFlowCtrlMode) {
6090
6091 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6092 }
6093 break;
6094
6095 case OID_SKGE_FLOWCTRL_STATUS:
6096 /* Check if it is the first active port */
6097 if (*pBuf == 0) {
6098
6099 *pBuf = pPrt->PFlowCtrlStatus;
6100 continue;
6101 }
6102
6103 /*
6104 * If we find an active port with a different flow
6105 * control status than the first one, we return a
6106 * value that indicates that the status is
6107 * indeterminated.
6108 */
6109 if (*pBuf != pPrt->PFlowCtrlStatus) {
6110
6111 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6112 }
6113 break;
6114
6115 case OID_SKGE_PHY_OPERATION_CAP:
6116 /* Check if it is the first active port */
6117 if (*pBuf == 0) {
6118
6119 *pBuf = pPrt->PMSCap;
6120 continue;
6121 }
6122
6123 /*
6124 * From a curious point of view the virtual port
6125 * is capable of all found capabilities.
6126 */
6127 *pBuf |= pPrt->PMSCap;
6128 break;
6129
6130 case OID_SKGE_PHY_OPERATION_MODE:
6131 /* Check if it is the first active port */
6132 if (*pBuf == 0) {
6133
6134 *pBuf = pPrt->PMSMode;
6135 continue;
6136 }
6137
6138 /*
6139 * If we find an active port with a different master/
6140 * slave mode than the first one, we return a value
6141 * that indicates that the mode is indeterminated.
6142 */
6143 if (*pBuf != pPrt->PMSMode) {
6144
6145 *pBuf = SK_MS_MODE_INDETERMINATED;
6146 }
6147 break;
6148
6149 case OID_SKGE_PHY_OPERATION_STATUS:
6150 /* Check if it is the first active port */
6151 if (*pBuf == 0) {
6152
6153 *pBuf = pPrt->PMSStatus;
6154 continue;
6155 }
6156
6157 /*
6158 * If we find an active port with a different master/
6159 * slave status than the first one, we return a
6160 * value that indicates that the status is
6161 * indeterminated.
6162 */
6163 if (*pBuf != pPrt->PMSStatus) {
6164
6165 *pBuf = SK_MS_STAT_INDETERMINATED;
6166 }
6167 break;
6168
6169 case OID_SKGE_SPEED_MODE:
6170 /* Check if it is the first active port */
6171 if (*pBuf == 0) {
6172
6173 *pBuf = pPrt->PLinkSpeed;
6174 continue;
6175 }
6176
6177 /*
6178 * If we find an active port with a different flow
6179 * control mode than the first one, we return a value
6180 * that indicates that the mode is indeterminated.
6181 */
6182 if (*pBuf != pPrt->PLinkSpeed) {
6183
6184 *pBuf = SK_LSPEED_INDETERMINATED;
6185 }
6186 break;
6187
6188 case OID_SKGE_SPEED_STATUS:
6189 /* Check if it is the first active port */
6190 if (*pBuf == 0) {
6191
6192 *pBuf = pPrt->PLinkSpeedUsed;
6193 continue;
6194 }
6195
6196 /*
6197 * If we find an active port with a different flow
6198 * control status than the first one, we return a
6199 * value that indicates that the status is
6200 * indeterminated.
6201 */
6202 if (*pBuf != pPrt->PLinkSpeedUsed) {
6203
6204 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6205 }
6206 break;
6207 }
6208 }
6209
6210 /*
6211 * If no port is active return an indeterminated answer
6212 */
6213 if (!PortActiveFlag) {
6214
6215 switch (Id) {
6216
6217 case OID_SKGE_LINK_CAP:
6218 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6219 break;
6220
6221 case OID_SKGE_LINK_MODE:
6222 *pBuf = SK_LMODE_INDETERMINATED;
6223 break;
6224
6225 case OID_SKGE_LINK_MODE_STATUS:
6226 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6227 break;
6228
6229 case OID_SKGE_LINK_STATUS:
6230 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6231 break;
6232
6233 case OID_SKGE_FLOWCTRL_CAP:
6234 case OID_SKGE_FLOWCTRL_MODE:
6235 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6236 break;
6237
6238 case OID_SKGE_FLOWCTRL_STATUS:
6239 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6240 break;
6241
6242 case OID_SKGE_PHY_OPERATION_CAP:
6243 *pBuf = SK_MS_CAP_INDETERMINATED;
6244 break;
6245
6246 case OID_SKGE_PHY_OPERATION_MODE:
6247 *pBuf = SK_MS_MODE_INDETERMINATED;
6248 break;
6249
6250 case OID_SKGE_PHY_OPERATION_STATUS:
6251 *pBuf = SK_MS_STAT_INDETERMINATED;
6252 break;
6253 case OID_SKGE_SPEED_CAP:
6254 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6255 break;
6256
6257 case OID_SKGE_SPEED_MODE:
6258 *pBuf = SK_LSPEED_INDETERMINATED;
6259 break;
6260
6261 case OID_SKGE_SPEED_STATUS:
6262 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6263 break;
6264 }
6265 }
6266}
6267
6268/*****************************************************************************
6269 *
6270 * CalculateLinkStatus - Determins the link status of a physical port
6271 *
6272 * Description:
6273 * Determins the link status the following way:
6274 * LSTAT_PHY_DOWN: Link is down
6275 * LSTAT_AUTONEG: Auto-negotiation failed
6276 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6277 * logically up.
6278 * LSTAT_LOG_UP: RLMT marked the port as up
6279 *
6280 * Returns:
6281 * Link status of physical port
6282 */
6283PNMI_STATIC SK_U8 CalculateLinkStatus(
6284SK_AC *pAC, /* Pointer to adapter context */
6285SK_IOC IoC, /* IO context handle */
6286unsigned int PhysPortIndex) /* Physical port index */
6287{
6288 SK_U8 Result;
6289
6290 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6291
6292 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6293 }
6294 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6295
6296 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6297 }
6298 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6299
6300 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6301 }
6302 else {
6303 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6304 }
6305
6306 return (Result);
6307}
6308
6309/*****************************************************************************
6310 *
6311 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6312 *
6313 * Description:
6314 * The COMMON module only tells us if the mode is half or full duplex.
6315 * But in the decade of auto sensing it is useful for the user to
6316 * know if the mode was negotiated or forced. Therefore we have a
6317 * look to the mode, which was last used by the negotiation process.
6318 *
6319 * Returns:
6320 * The link mode status
6321 */
6322PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6323SK_AC *pAC, /* Pointer to adapter context */
6324SK_IOC IoC, /* IO context handle */
6325unsigned int PhysPortIndex) /* Physical port index */
6326{
6327 SK_U8 Result;
6328
6329 /* Get the current mode, which can be full or half duplex */
6330 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6331
6332 /* Check if no valid mode could be found (link is down) */
6333 if (Result < SK_LMODE_STAT_HALF) {
6334
6335 Result = SK_LMODE_STAT_UNKNOWN;
6336 }
6337 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6338
6339 /*
6340 * Auto-negotiation was used to bring up the link. Change
6341 * the already found duplex status that it indicates
6342 * auto-negotiation was involved.
6343 */
6344 if (Result == SK_LMODE_STAT_HALF) {
6345
6346 Result = SK_LMODE_STAT_AUTOHALF;
6347 }
6348 else if (Result == SK_LMODE_STAT_FULL) {
6349
6350 Result = SK_LMODE_STAT_AUTOFULL;
6351 }
6352 }
6353
6354 return (Result);
6355}
6356
6357/*****************************************************************************
6358 *
6359 * GetVpdKeyArr - Obtain an array of VPD keys
6360 *
6361 * Description:
6362 * Read the VPD keys and build an array of VPD keys, which are
6363 * easy to access.
6364 *
6365 * Returns:
6366 * SK_PNMI_ERR_OK Task successfully performed.
6367 * SK_PNMI_ERR_GENERAL Something went wrong.
6368 */
6369PNMI_STATIC int GetVpdKeyArr(
6370SK_AC *pAC, /* Pointer to adapter context */
6371SK_IOC IoC, /* IO context handle */
6372char *pKeyArr, /* Ptr KeyArray */
6373unsigned int KeyArrLen, /* Length of array in bytes */
6374unsigned int *pKeyNo) /* Number of keys */
6375{
6376 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6377 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6378 unsigned int StartOffset;
6379 unsigned int Offset;
6380 int Index;
6381 int Ret;
6382
6383
6384 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6385
6386 /*
6387 * Get VPD key list
6388 */
6389 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6390 (int *)pKeyNo);
6391 if (Ret > 0) {
6392
6393 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6394 SK_PNMI_ERR014MSG);
6395
6396 return (SK_PNMI_ERR_GENERAL);
6397 }
6398 /* If no keys are available return now */
6399 if (*pKeyNo == 0 || BufKeysLen == 0) {
6400
6401 return (SK_PNMI_ERR_OK);
6402 }
6403 /*
6404 * If the key list is too long for us trunc it and give a
6405 * errorlog notification. This case should not happen because
6406 * the maximum number of keys is limited due to RAM limitations
6407 */
6408 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6409
6410 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6411 SK_PNMI_ERR015MSG);
6412
6413 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6414 }
6415
6416 /*
6417 * Now build an array of fixed string length size and copy
6418 * the keys together.
6419 */
6420 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6421 Offset ++) {
6422
6423 if (BufKeys[Offset] != 0) {
6424
6425 continue;
6426 }
6427
6428 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6429
6430 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6431 SK_PNMI_ERR016MSG);
6432 return (SK_PNMI_ERR_GENERAL);
6433 }
6434
6435 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6436 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6437
6438 Index ++;
6439 StartOffset = Offset + 1;
6440 }
6441
6442 /* Last key not zero terminated? Get it anyway */
6443 if (StartOffset < Offset) {
6444
6445 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6446 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6447 }
6448
6449 return (SK_PNMI_ERR_OK);
6450}
6451
6452/*****************************************************************************
6453 *
6454 * SirqUpdate - Let the SIRQ update its internal values
6455 *
6456 * Description:
6457 * Just to be sure that the SIRQ module holds its internal data
6458 * structures up to date, we send an update event before we make
6459 * any access.
6460 *
6461 * Returns:
6462 * SK_PNMI_ERR_OK Task successfully performed.
6463 * SK_PNMI_ERR_GENERAL Something went wrong.
6464 */
6465PNMI_STATIC int SirqUpdate(
6466SK_AC *pAC, /* Pointer to adapter context */
6467SK_IOC IoC) /* IO context handle */
6468{
6469 SK_EVPARA EventParam;
6470
6471
6472 /* Was the module already updated during the current PNMI call? */
6473 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6474
6475 return (SK_PNMI_ERR_OK);
6476 }
6477
6478 /* Send an synchronuous update event to the module */
6479 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6480 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6481
6482 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6483 SK_PNMI_ERR047MSG);
6484
6485 return (SK_PNMI_ERR_GENERAL);
6486 }
6487
6488 return (SK_PNMI_ERR_OK);
6489}
6490
6491/*****************************************************************************
6492 *
6493 * RlmtUpdate - Let the RLMT update its internal values
6494 *
6495 * Description:
6496 * Just to be sure that the RLMT module holds its internal data
6497 * structures up to date, we send an update event before we make
6498 * any access.
6499 *
6500 * Returns:
6501 * SK_PNMI_ERR_OK Task successfully performed.
6502 * SK_PNMI_ERR_GENERAL Something went wrong.
6503 */
6504PNMI_STATIC int RlmtUpdate(
6505SK_AC *pAC, /* Pointer to adapter context */
6506SK_IOC IoC, /* IO context handle */
6507SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6508{
6509 SK_EVPARA EventParam;
6510
6511
6512 /* Was the module already updated during the current PNMI call? */
6513 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6514
6515 return (SK_PNMI_ERR_OK);
6516 }
6517
6518 /* Send an synchronuous update event to the module */
6519 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6520 EventParam.Para32[0] = NetIndex;
6521 EventParam.Para32[1] = (SK_U32)-1;
6522 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6523
6524 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6525 SK_PNMI_ERR048MSG);
6526
6527 return (SK_PNMI_ERR_GENERAL);
6528 }
6529
6530 return (SK_PNMI_ERR_OK);
6531}
6532
6533/*****************************************************************************
6534 *
6535 * MacUpdate - Force the XMAC to output the current statistic
6536 *
6537 * Description:
6538 * The XMAC holds its statistic internally. To obtain the current
6539 * values we must send a command so that the statistic data will
6540 * be written to a predefined memory area on the adapter.
6541 *
6542 * Returns:
6543 * SK_PNMI_ERR_OK Task successfully performed.
6544 * SK_PNMI_ERR_GENERAL Something went wrong.
6545 */
6546PNMI_STATIC int MacUpdate(
6547SK_AC *pAC, /* Pointer to adapter context */
6548SK_IOC IoC, /* IO context handle */
6549unsigned int FirstMac, /* Index of the first Mac to be updated */
6550unsigned int LastMac) /* Index of the last Mac to be updated */
6551{
6552 unsigned int MacIndex;
6553
6554 /*
6555 * Were the statistics already updated during the
6556 * current PNMI call?
6557 */
6558 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6559
6560 return (SK_PNMI_ERR_OK);
6561 }
6562
6563 /* Send an update command to all MACs specified */
6564 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6565
6566 /*
6567 * 2002-09-13 pweber: Freeze the current SW counters.
6568 * (That should be done as close as
6569 * possible to the update of the
6570 * HW counters)
6571 */
6572 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6573 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6574 }
6575
6576 /* 2002-09-13 pweber: Update the HW counter */
6577 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6578
6579 return (SK_PNMI_ERR_GENERAL);
6580 }
6581 }
6582
6583 return (SK_PNMI_ERR_OK);
6584}
6585
6586/*****************************************************************************
6587 *
6588 * GetStatVal - Retrieve an XMAC statistic counter
6589 *
6590 * Description:
6591 * Retrieves the statistic counter of a virtual or physical port. The
6592 * virtual port is identified by the index 0. It consists of all
6593 * currently active ports. To obtain the counter value for this port
6594 * we must add the statistic counter of all active ports. To grant
6595 * continuous counter values for the virtual port even when port
6596 * switches occur we must additionally add a delta value, which was
6597 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6598 *
6599 * Returns:
6600 * Requested statistic value
6601 */
6602PNMI_STATIC SK_U64 GetStatVal(
6603SK_AC *pAC, /* Pointer to adapter context */
6604SK_IOC IoC, /* IO context handle */
6605unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6606unsigned int StatIndex, /* Index to statistic value */
6607SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6608{
6609 unsigned int PhysPortIndex;
6610 unsigned int PhysPortMax;
6611 SK_U64 Val = 0;
6612
6613
6614 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6615
6616 PhysPortIndex = NetIndex;
6617
6618 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6619 }
6620 else { /* Single Net mode */
6621
6622 if (LogPortIndex == 0) {
6623
6624 PhysPortMax = pAC->GIni.GIMacsFound;
6625
6626 /* Add counter of all active ports */
6627 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6628 PhysPortIndex ++) {
6629
6630 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6631
6632 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6633 }
6634 }
6635
6636 /* Correct value because of port switches */
6637 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6638 }
6639 else {
6640 /* Get counter value of physical port */
6641 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6642
6643 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6644 }
6645 }
6646 return (Val);
6647}
6648
6649/*****************************************************************************
6650 *
6651 * GetPhysStatVal - Get counter value for physical port
6652 *
6653 * Description:
6654 * Builds a 64bit counter value. Except for the octet counters
6655 * the lower 32bit are counted in hardware and the upper 32bit
6656 * in software by monitoring counter overflow interrupts in the
6657 * event handler. To grant continous counter values during XMAC
6658 * resets (caused by a workaround) we must add a delta value.
6659 * The delta was calculated in the event handler when a
6660 * SK_PNMI_EVT_XMAC_RESET was received.
6661 *
6662 * Returns:
6663 * Counter value
6664 */
6665PNMI_STATIC SK_U64 GetPhysStatVal(
6666SK_AC *pAC, /* Pointer to adapter context */
6667SK_IOC IoC, /* IO context handle */
6668unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6669unsigned int StatIndex) /* Index to statistic value */
6670{
6671 SK_U64 Val = 0;
6672 SK_U32 LowVal = 0;
6673 SK_U32 HighVal = 0;
6674 SK_U16 Word;
6675 int MacType;
6676 unsigned int HelpIndex;
6677 SK_GEPORT *pPrt;
6678
6679 SK_PNMI_PORT *pPnmiPrt;
6680 SK_GEMACFUNC *pFnMac;
6681
6682 pPrt = &pAC->GIni.GP[PhysPortIndex];
6683
6684 MacType = pAC->GIni.GIMacType;
6685
6686 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6687 if (MacType == SK_MAC_XMAC) {
6688 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6689 }
6690 else {
6691 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6692 }
6693
6694 pFnMac = &pAC->GIni.GIFunc;
6695
6696 switch (StatIndex) {
6697 case SK_PNMI_HTX:
6698 if (MacType == SK_MAC_GMAC) {
6699 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6700 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6701 &LowVal);
6702 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6703 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6704 &HighVal);
6705 LowVal += HighVal;
6706 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6707 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6708 &HighVal);
6709 LowVal += HighVal;
6710 }
6711 else {
6712 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6713 StatAddr[StatIndex][MacType].Reg,
6714 &LowVal);
6715 }
6716 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6717 break;
6718
6719 case SK_PNMI_HRX:
6720 if (MacType == SK_MAC_GMAC) {
6721 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6722 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6723 &LowVal);
6724 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6725 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6726 &HighVal);
6727 LowVal += HighVal;
6728 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6729 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6730 &HighVal);
6731 LowVal += HighVal;
6732 }
6733 else {
6734 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6735 StatAddr[StatIndex][MacType].Reg,
6736 &LowVal);
6737 }
6738 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6739 break;
6740
6741 case SK_PNMI_HTX_OCTET:
6742 case SK_PNMI_HRX_OCTET:
6743 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6744 StatAddr[StatIndex][MacType].Reg,
6745 &HighVal);
6746 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6747 StatAddr[StatIndex + 1][MacType].Reg,
6748 &LowVal);
6749 break;
6750
6751 case SK_PNMI_HTX_BURST:
6752 case SK_PNMI_HTX_EXCESS_DEF:
6753 case SK_PNMI_HTX_CARRIER:
6754 /* Not supported by GMAC */
6755 if (MacType == SK_MAC_GMAC) {
6756 return (Val);
6757 }
6758
6759 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6760 StatAddr[StatIndex][MacType].Reg,
6761 &LowVal);
6762 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6763 break;
6764
6765 case SK_PNMI_HTX_MACC:
6766 /* GMAC only supports PAUSE MAC control frames */
6767 if (MacType == SK_MAC_GMAC) {
6768 HelpIndex = SK_PNMI_HTX_PMACC;
6769 }
6770 else {
6771 HelpIndex = StatIndex;
6772 }
6773
6774 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6775 StatAddr[HelpIndex][MacType].Reg,
6776 &LowVal);
6777
6778 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6779 break;
6780
6781 case SK_PNMI_HTX_COL:
6782 case SK_PNMI_HRX_UNDERSIZE:
6783 /* Not supported by XMAC */
6784 if (MacType == SK_MAC_XMAC) {
6785 return (Val);
6786 }
6787
6788 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6789 StatAddr[StatIndex][MacType].Reg,
6790 &LowVal);
6791 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6792 break;
6793
6794 case SK_PNMI_HTX_DEFFERAL:
6795 /* Not supported by GMAC */
6796 if (MacType == SK_MAC_GMAC) {
6797 return (Val);
6798 }
6799
6800 /*
6801 * XMAC counts frames with deferred transmission
6802 * even in full-duplex mode.
6803 *
6804 * In full-duplex mode the counter remains constant!
6805 */
6806 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6807 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6808
6809 LowVal = 0;
6810 HighVal = 0;
6811 }
6812 else {
6813 /* Otherwise get contents of hardware register */
6814 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6815 StatAddr[StatIndex][MacType].Reg,
6816 &LowVal);
6817 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6818 }
6819 break;
6820
6821 case SK_PNMI_HRX_BADOCTET:
6822 /* Not supported by XMAC */
6823 if (MacType == SK_MAC_XMAC) {
6824 return (Val);
6825 }
6826
6827 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6828 StatAddr[StatIndex][MacType].Reg,
6829 &HighVal);
6830 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6831 StatAddr[StatIndex + 1][MacType].Reg,
6832 &LowVal);
6833 break;
6834
6835 case SK_PNMI_HTX_OCTETLOW:
6836 case SK_PNMI_HRX_OCTETLOW:
6837 case SK_PNMI_HRX_BADOCTETLOW:
6838 return (Val);
6839
6840 case SK_PNMI_HRX_LONGFRAMES:
6841 /* For XMAC the SW counter is managed by PNMI */
6842 if (MacType == SK_MAC_XMAC) {
6843 return (pPnmiPrt->StatRxLongFrameCts);
6844 }
6845
6846 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6847 StatAddr[StatIndex][MacType].Reg,
6848 &LowVal);
6849 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6850 break;
6851
6852 case SK_PNMI_HRX_TOO_LONG:
6853 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6854 StatAddr[StatIndex][MacType].Reg,
6855 &LowVal);
6856 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6857
6858 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6859
6860 if (MacType == SK_MAC_GMAC) {
6861 /* For GMAC the SW counter is additionally managed by PNMI */
6862 Val += pPnmiPrt->StatRxFrameTooLongCts;
6863 }
6864 else {
6865 /*
6866 * Frames longer than IEEE 802.3 frame max size are counted
6867 * by XMAC in frame_too_long counter even reception of long
6868 * frames was enabled and the frame was correct.
6869 * So correct the value by subtracting RxLongFrame counter.
6870 */
6871 Val -= pPnmiPrt->StatRxLongFrameCts;
6872 }
6873
6874 LowVal = (SK_U32)Val;
6875 HighVal = (SK_U32)(Val >> 32);
6876 break;
6877
6878 case SK_PNMI_HRX_SHORTS:
6879 /* Not supported by GMAC */
6880 if (MacType == SK_MAC_GMAC) {
6881 /* GM_RXE_FRAG?? */
6882 return (Val);
6883 }
6884
6885 /*
6886 * XMAC counts short frame errors even if link down (#10620)
6887 *
6888 * If link-down the counter remains constant
6889 */
6890 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
6891
6892 /* Otherwise get incremental difference */
6893 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6894 StatAddr[StatIndex][MacType].Reg,
6895 &LowVal);
6896 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6897
6898 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6899 Val -= pPnmiPrt->RxShortZeroMark;
6900
6901 LowVal = (SK_U32)Val;
6902 HighVal = (SK_U32)(Val >> 32);
6903 }
6904 break;
6905
6906 case SK_PNMI_HRX_MACC:
6907 case SK_PNMI_HRX_MACC_UNKWN:
6908 case SK_PNMI_HRX_BURST:
6909 case SK_PNMI_HRX_MISSED:
6910 case SK_PNMI_HRX_FRAMING:
6911 case SK_PNMI_HRX_CARRIER:
6912 case SK_PNMI_HRX_IRLENGTH:
6913 case SK_PNMI_HRX_SYMBOL:
6914 case SK_PNMI_HRX_CEXT:
6915 /* Not supported by GMAC */
6916 if (MacType == SK_MAC_GMAC) {
6917 return (Val);
6918 }
6919
6920 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6921 StatAddr[StatIndex][MacType].Reg,
6922 &LowVal);
6923 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6924 break;
6925
6926 case SK_PNMI_HRX_PMACC_ERR:
6927 /* For GMAC the SW counter is managed by PNMI */
6928 if (MacType == SK_MAC_GMAC) {
6929 return (pPnmiPrt->StatRxPMaccErr);
6930 }
6931
6932 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6933 StatAddr[StatIndex][MacType].Reg,
6934 &LowVal);
6935 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6936 break;
6937
6938 /* SW counter managed by PNMI */
6939 case SK_PNMI_HTX_SYNC:
6940 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
6941 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
6942 break;
6943
6944 /* SW counter managed by PNMI */
6945 case SK_PNMI_HTX_SYNC_OCTET:
6946 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
6947 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
6948 break;
6949
6950 case SK_PNMI_HRX_FCS:
6951 /*
6952 * Broadcom filters FCS errors and counts it in
6953 * Receive Error Counter register
6954 */
6955 if (pPrt->PhyType == SK_PHY_BCOM) {
6956 /* do not read while not initialized (PHY_READ hangs!)*/
6957 if (pPrt->PState != SK_PRT_RESET) {
6958 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
6959
6960 LowVal = Word;
6961 }
6962 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6963 }
6964 else {
6965 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6966 StatAddr[StatIndex][MacType].Reg,
6967 &LowVal);
6968 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6969 }
6970 break;
6971
6972 default:
6973 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6974 StatAddr[StatIndex][MacType].Reg,
6975 &LowVal);
6976 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6977 break;
6978 }
6979
6980 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6981
6982 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
6983 Val += pPnmiPrt->CounterOffset[StatIndex];
6984
6985 return (Val);
6986}
6987
6988/*****************************************************************************
6989 *
6990 * ResetCounter - Set all counters and timestamps to zero
6991 *
6992 * Description:
6993 * Notifies other common modules which store statistic data to
6994 * reset their counters and finally reset our own counters.
6995 *
6996 * Returns:
6997 * Nothing
6998 */
6999PNMI_STATIC void ResetCounter(
7000SK_AC *pAC, /* Pointer to adapter context */
7001SK_IOC IoC, /* IO context handle */
7002SK_U32 NetIndex)
7003{
7004 unsigned int PhysPortIndex;
7005 SK_EVPARA EventParam;
7006
7007
7008 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7009
7010 /* Notify sensor module */
7011 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7012
7013 /* Notify RLMT module */
7014 EventParam.Para32[0] = NetIndex;
7015 EventParam.Para32[1] = (SK_U32)-1;
7016 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7017 EventParam.Para32[1] = 0;
7018
7019 /* Notify SIRQ module */
7020 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7021
7022 /* Notify CSUM module */
7023#ifdef SK_USE_CSUM
7024 EventParam.Para32[0] = NetIndex;
7025 EventParam.Para32[1] = (SK_U32)-1;
7026 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7027 EventParam);
7028#endif /* SK_USE_CSUM */
7029
7030 /* Clear XMAC statistic */
7031 for (PhysPortIndex = 0; PhysPortIndex <
7032 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7033
7034 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7035
7036 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7037 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7038 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7039 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7040 PhysPortIndex].CounterOffset));
7041 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7042 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7043 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7044 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7045 PhysPortIndex].StatSyncOctetsCts));
7046 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7047 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7048 PhysPortIndex].StatRxLongFrameCts));
7049 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7050 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7051 PhysPortIndex].StatRxFrameTooLongCts));
7052 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7053 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7054 PhysPortIndex].StatRxPMaccErr));
7055 }
7056
7057 /*
7058 * Clear local statistics
7059 */
7060 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7061 sizeof(pAC->Pnmi.VirtualCounterOffset));
7062 pAC->Pnmi.RlmtChangeCts = 0;
7063 pAC->Pnmi.RlmtChangeTime = 0;
7064 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7065 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7066 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7067 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7068 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7069 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7070 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7071 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7072 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7073 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7074 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7075 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7076 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7077 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7078}
7079
7080/*****************************************************************************
7081 *
7082 * GetTrapEntry - Get an entry in the trap buffer
7083 *
7084 * Description:
7085 * The trap buffer stores various events. A user application somehow
7086 * gets notified that an event occured and retrieves the trap buffer
7087 * contens (or simply polls the buffer). The buffer is organized as
7088 * a ring which stores the newest traps at the beginning. The oldest
7089 * traps are overwritten by the newest ones. Each trap entry has a
7090 * unique number, so that applications may detect new trap entries.
7091 *
7092 * Returns:
7093 * A pointer to the trap entry
7094 */
7095PNMI_STATIC char* GetTrapEntry(
7096SK_AC *pAC, /* Pointer to adapter context */
7097SK_U32 TrapId, /* SNMP ID of the trap */
7098unsigned int Size) /* Space needed for trap entry */
7099{
7100 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7101 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7102 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7103 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7104 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7105 int Wrap;
7106 unsigned int NeededSpace;
7107 unsigned int EntrySize;
7108 SK_U32 Val32;
7109 SK_U64 Val64;
7110
7111
7112 /* Last byte of entry will get a copy of the entry length */
7113 Size ++;
7114
7115 /*
7116 * Calculate needed buffer space */
7117 if (Beg >= Size) {
7118
7119 NeededSpace = Size;
7120 Wrap = SK_FALSE;
7121 }
7122 else {
7123 NeededSpace = Beg + Size;
7124 Wrap = SK_TRUE;
7125 }
7126
7127 /*
7128 * Check if enough buffer space is provided. Otherwise
7129 * free some entries. Leave one byte space between begin
7130 * and end of buffer to make it possible to detect whether
7131 * the buffer is full or empty
7132 */
7133 while (BufFree < NeededSpace + 1) {
7134
7135 if (End == 0) {
7136
7137 End = SK_PNMI_TRAP_QUEUE_LEN;
7138 }
7139
7140 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7141 BufFree += EntrySize;
7142 End -= EntrySize;
7143#ifdef DEBUG
7144 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7145#endif /* DEBUG */
7146 if (End == BufPad) {
7147#ifdef DEBUG
7148 SK_MEMSET(pBuf, (char)(-1), End);
7149#endif /* DEBUG */
7150 BufFree += End;
7151 End = 0;
7152 BufPad = 0;
7153 }
7154 }
7155
7156 /*
7157 * Insert new entry as first entry. Newest entries are
7158 * stored at the beginning of the queue.
7159 */
7160 if (Wrap) {
7161
7162 BufPad = Beg;
7163 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7164 }
7165 else {
7166 Beg = Beg - Size;
7167 }
7168 BufFree -= NeededSpace;
7169
7170 /* Save the current offsets */
7171 pAC->Pnmi.TrapQueueBeg = Beg;
7172 pAC->Pnmi.TrapQueueEnd = End;
7173 pAC->Pnmi.TrapBufPad = BufPad;
7174 pAC->Pnmi.TrapBufFree = BufFree;
7175
7176 /* Initialize the trap entry */
7177 *(pBuf + Beg + Size - 1) = (char)Size;
7178 *(pBuf + Beg) = (char)Size;
7179 Val32 = (pAC->Pnmi.TrapUnique) ++;
7180 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7181 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7182 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7183 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7184
7185 return (pBuf + Beg);
7186}
7187
7188/*****************************************************************************
7189 *
7190 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7191 *
7192 * Description:
7193 * On a query of the TRAP OID the trap buffer contents will be
7194 * copied continuously to the request buffer, which must be large
7195 * enough. No length check is performed.
7196 *
7197 * Returns:
7198 * Nothing
7199 */
7200PNMI_STATIC void CopyTrapQueue(
7201SK_AC *pAC, /* Pointer to adapter context */
7202char *pDstBuf) /* Buffer to which the queued traps will be copied */
7203{
7204 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7205 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7206 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7207 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7208 unsigned int Len;
7209 unsigned int DstOff = 0;
7210
7211
7212 while (Trap != End) {
7213
7214 Len = (unsigned int)*(pBuf + Trap);
7215
7216 /*
7217 * Last byte containing a copy of the length will
7218 * not be copied.
7219 */
7220 *(pDstBuf + DstOff) = (char)(Len - 1);
7221 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7222 DstOff += Len - 1;
7223
7224 Trap += Len;
7225 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7226
7227 Trap = BufPad;
7228 }
7229 }
7230}
7231
7232/*****************************************************************************
7233 *
7234 * GetTrapQueueLen - Get the length of the trap buffer
7235 *
7236 * Description:
7237 * Evaluates the number of currently stored traps and the needed
7238 * buffer size to retrieve them.
7239 *
7240 * Returns:
7241 * Nothing
7242 */
7243PNMI_STATIC void GetTrapQueueLen(
7244SK_AC *pAC, /* Pointer to adapter context */
7245unsigned int *pLen, /* Length in Bytes of all queued traps */
7246unsigned int *pEntries) /* Returns number of trapes stored in queue */
7247{
7248 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7249 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7250 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7251 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7252 unsigned int Len;
7253 unsigned int Entries = 0;
7254 unsigned int TotalLen = 0;
7255
7256
7257 while (Trap != End) {
7258
7259 Len = (unsigned int)*(pBuf + Trap);
7260 TotalLen += Len - 1;
7261 Entries ++;
7262
7263 Trap += Len;
7264 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7265
7266 Trap = BufPad;
7267 }
7268 }
7269
7270 *pEntries = Entries;
7271 *pLen = TotalLen;
7272}
7273
7274/*****************************************************************************
7275 *
7276 * QueueSimpleTrap - Store a simple trap to the trap buffer
7277 *
7278 * Description:
7279 * A simple trap is a trap with now additional data. It consists
7280 * simply of a trap code.
7281 *
7282 * Returns:
7283 * Nothing
7284 */
7285PNMI_STATIC void QueueSimpleTrap(
7286SK_AC *pAC, /* Pointer to adapter context */
7287SK_U32 TrapId) /* Type of sensor trap */
7288{
7289 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7290}
7291
7292/*****************************************************************************
7293 *
7294 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7295 *
7296 * Description:
7297 * Gets an entry in the trap buffer and fills it with sensor related
7298 * data.
7299 *
7300 * Returns:
7301 * Nothing
7302 */
7303PNMI_STATIC void QueueSensorTrap(
7304SK_AC *pAC, /* Pointer to adapter context */
7305SK_U32 TrapId, /* Type of sensor trap */
7306unsigned int SensorIndex) /* Index of sensor which caused the trap */
7307{
7308 char *pBuf;
7309 unsigned int Offset;
7310 unsigned int DescrLen;
7311 SK_U32 Val32;
7312
7313
7314 /* Get trap buffer entry */
7315 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7316 pBuf = GetTrapEntry(pAC, TrapId,
7317 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7318 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7319
7320 /* Store additionally sensor trap related data */
7321 Val32 = OID_SKGE_SENSOR_INDEX;
7322 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7323 *(pBuf + Offset + 4) = 4;
7324 Val32 = (SK_U32)SensorIndex;
7325 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7326 Offset += 9;
7327
7328 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7329 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7330 *(pBuf + Offset + 4) = (char)DescrLen;
7331 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7332 DescrLen);
7333 Offset += DescrLen + 5;
7334
7335 Val32 = OID_SKGE_SENSOR_TYPE;
7336 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7337 *(pBuf + Offset + 4) = 1;
7338 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7339 Offset += 6;
7340
7341 Val32 = OID_SKGE_SENSOR_VALUE;
7342 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7343 *(pBuf + Offset + 4) = 4;
7344 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7345 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7346}
7347
7348/*****************************************************************************
7349 *
7350 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7351 *
7352 * Description:
7353 * Nothing further to explain.
7354 *
7355 * Returns:
7356 * Nothing
7357 */
7358PNMI_STATIC void QueueRlmtNewMacTrap(
7359SK_AC *pAC, /* Pointer to adapter context */
7360unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7361{
7362 char *pBuf;
7363 SK_U32 Val32;
7364
7365
7366 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7367 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7368
7369 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7370 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7371 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7372 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7373}
7374
7375/*****************************************************************************
7376 *
7377 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7378 *
7379 * Description:
7380 * Nothing further to explain.
7381 *
7382 * Returns:
7383 * Nothing
7384 */
7385PNMI_STATIC void QueueRlmtPortTrap(
7386SK_AC *pAC, /* Pointer to adapter context */
7387SK_U32 TrapId, /* Type of RLMT port trap */
7388unsigned int PortIndex) /* Index of the port, which changed its state */
7389{
7390 char *pBuf;
7391 SK_U32 Val32;
7392
7393
7394 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7395
7396 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7397 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7398 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7399 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7400}
7401
7402/*****************************************************************************
7403 *
7404 * CopyMac - Copies a MAC address
7405 *
7406 * Description:
7407 * Nothing further to explain.
7408 *
7409 * Returns:
7410 * Nothing
7411 */
7412PNMI_STATIC void CopyMac(
7413char *pDst, /* Pointer to destination buffer */
7414SK_MAC_ADDR *pMac) /* Pointer of Source */
7415{
7416 int i;
7417
7418
7419 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7420
7421 *(pDst + i) = pMac->a[i];
7422 }
7423}
7424
7425#ifdef SK_POWER_MGMT
7426/*****************************************************************************
7427 *
7428 * PowerManagement - OID handler function of PowerManagement OIDs
7429 *
7430 * Description:
7431 * The code is simple. No description necessary.
7432 *
7433 * Returns:
7434 * SK_PNMI_ERR_OK The request was successfully performed.
7435 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7436 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7437 * the correct data (e.g. a 32bit value is
7438 * needed, but a 16 bit value was passed).
7439 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7440 * exist (e.g. port instance 3 on a two port
7441 * adapter.
7442 */
7443
7444PNMI_STATIC int PowerManagement(
7445SK_AC *pAC, /* Pointer to adapter context */
7446SK_IOC IoC, /* IO context handle */
7447int Action, /* Get/PreSet/Set action */
7448SK_U32 Id, /* Object ID that is to be processed */
7449char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7450unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7451SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7452unsigned int TableIndex, /* Index to the Id table */
7453SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7454{
7455
7456 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7457
7458 /*
7459 * Check instance. We only handle single instance variables
7460 */
7461 if (Instance != (SK_U32)(-1) && Instance != 1) {
7462
7463 *pLen = 0;
7464 return (SK_PNMI_ERR_UNKNOWN_INST);
7465 }
7466
7467
7468 /* Check length */
7469 switch (Id) {
7470
7471 case OID_PNP_CAPABILITIES:
7472 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7473
7474 *pLen = sizeof(SK_PNP_CAPABILITIES);
7475 return (SK_PNMI_ERR_TOO_SHORT);
7476 }
7477 break;
7478
7479 case OID_PNP_SET_POWER:
7480 case OID_PNP_QUERY_POWER:
7481 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7482 {
7483 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7484 return (SK_PNMI_ERR_TOO_SHORT);
7485 }
7486 break;
7487
7488 case OID_PNP_ADD_WAKE_UP_PATTERN:
7489 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7490 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7491
7492 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7493 return (SK_PNMI_ERR_TOO_SHORT);
7494 }
7495 break;
7496
7497 case OID_PNP_ENABLE_WAKE_UP:
7498 if (*pLen < sizeof(SK_U32)) {
7499
7500 *pLen = sizeof(SK_U32);
7501 return (SK_PNMI_ERR_TOO_SHORT);
7502 }
7503 break;
7504 }
7505
7506 /*
7507 * Perform action
7508 */
7509 if (Action == SK_PNMI_GET) {
7510
7511 /*
7512 * Get value
7513 */
7514 switch (Id) {
7515
7516 case OID_PNP_CAPABILITIES:
7517 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7518 break;
7519
7520 case OID_PNP_QUERY_POWER:
7521 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7522 the miniport to indicate whether it can transition its NIC
7523 to the low-power state.
7524 A miniport driver must always return NDIS_STATUS_SUCCESS
7525 to a query of OID_PNP_QUERY_POWER. */
7526 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7527 RetCode = SK_PNMI_ERR_OK;
7528 break;
7529
7530 /* NDIS handles these OIDs as write-only.
7531 * So in case of get action the buffer with written length = 0
7532 * is returned
7533 */
7534 case OID_PNP_SET_POWER:
7535 case OID_PNP_ADD_WAKE_UP_PATTERN:
7536 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7537 *pLen = 0;
7538 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7539 break;
7540
7541 case OID_PNP_ENABLE_WAKE_UP:
7542 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7543 break;
7544
7545 default:
7546 RetCode = SK_PNMI_ERR_GENERAL;
7547 break;
7548 }
7549
7550 return (RetCode);
7551 }
7552
7553
7554 /*
7555 * Perform preset or set
7556 */
7557
7558 /* POWER module does not support PRESET action */
7559 if (Action == SK_PNMI_PRESET) {
7560 return (SK_PNMI_ERR_OK);
7561 }
7562
7563 switch (Id) {
7564 case OID_PNP_SET_POWER:
7565 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7566 break;
7567
7568 case OID_PNP_ADD_WAKE_UP_PATTERN:
7569 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7570 break;
7571
7572 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7573 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7574 break;
7575
7576 case OID_PNP_ENABLE_WAKE_UP:
7577 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7578 break;
7579
7580 default:
7581 RetCode = SK_PNMI_ERR_READ_ONLY;
7582 }
7583
7584 return (RetCode);
7585}
7586#endif /* SK_POWER_MGMT */
7587
7588#ifdef SK_DIAG_SUPPORT
7589/*****************************************************************************
7590 *
7591 * DiagActions - OID handler function of Diagnostic driver
7592 *
7593 * Description:
7594 * The code is simple. No description necessary.
7595 *
7596 * Returns:
7597 * SK_PNMI_ERR_OK The request was successfully performed.
7598 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7599 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7600 * the correct data (e.g. a 32bit value is
7601 * needed, but a 16 bit value was passed).
7602 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7603 * exist (e.g. port instance 3 on a two port
7604 * adapter.
7605 */
7606
7607PNMI_STATIC int DiagActions(
7608SK_AC *pAC, /* Pointer to adapter context */
7609SK_IOC IoC, /* IO context handle */
7610int Action, /* GET/PRESET/SET action */
7611SK_U32 Id, /* Object ID that is to be processed */
7612char *pBuf, /* Buffer used for the management data transfer */
7613unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7614SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7615unsigned int TableIndex, /* Index to the Id table */
7616SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7617{
7618
7619 SK_U32 DiagStatus;
7620 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7621
7622 /*
7623 * Check instance. We only handle single instance variables.
7624 */
7625 if (Instance != (SK_U32)(-1) && Instance != 1) {
7626
7627 *pLen = 0;
7628 return (SK_PNMI_ERR_UNKNOWN_INST);
7629 }
7630
7631 /*
7632 * Check length.
7633 */
7634 switch (Id) {
7635
7636 case OID_SKGE_DIAG_MODE:
7637 if (*pLen < sizeof(SK_U32)) {
7638
7639 *pLen = sizeof(SK_U32);
7640 return (SK_PNMI_ERR_TOO_SHORT);
7641 }
7642 break;
7643
7644 default:
7645 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7646 *pLen = 0;
7647 return (SK_PNMI_ERR_GENERAL);
7648 }
7649
7650 /* Perform action. */
7651
7652 /* GET value. */
7653 if (Action == SK_PNMI_GET) {
7654
7655 switch (Id) {
7656
7657 case OID_SKGE_DIAG_MODE:
7658 DiagStatus = pAC->Pnmi.DiagAttached;
7659 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7660 *pLen = sizeof(SK_U32);
7661 RetCode = SK_PNMI_ERR_OK;
7662 break;
7663
7664 default:
7665 *pLen = 0;
7666 RetCode = SK_PNMI_ERR_GENERAL;
7667 break;
7668 }
7669 return (RetCode);
7670 }
7671
7672 /* From here SET or PRESET value. */
7673
7674 /* PRESET value is not supported. */
7675 if (Action == SK_PNMI_PRESET) {
7676 return (SK_PNMI_ERR_OK);
7677 }
7678
7679 /* SET value. */
7680 switch (Id) {
7681 case OID_SKGE_DIAG_MODE:
7682
7683 /* Handle the SET. */
7684 switch (*pBuf) {
7685
7686 /* Attach the DIAG to this adapter. */
7687 case SK_DIAG_ATTACHED:
7688 /* Check if we come from running */
7689 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7690
7691 RetCode = SkDrvLeaveDiagMode(pAC);
7692
7693 }
7694 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7695
7696 RetCode = SK_PNMI_ERR_OK;
7697 }
7698
7699 else {
7700
7701 RetCode = SK_PNMI_ERR_GENERAL;
7702
7703 }
7704
7705 if (RetCode == SK_PNMI_ERR_OK) {
7706
7707 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7708 }
7709 break;
7710
7711 /* Enter the DIAG mode in the driver. */
7712 case SK_DIAG_RUNNING:
7713 RetCode = SK_PNMI_ERR_OK;
7714
7715 /*
7716 * If DiagAttached is set, we can tell the driver
7717 * to enter the DIAG mode.
7718 */
7719 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7720 /* If DiagMode is not active, we can enter it. */
7721 if (!pAC->DiagModeActive) {
7722
7723 RetCode = SkDrvEnterDiagMode(pAC);
7724 }
7725 else {
7726
7727 RetCode = SK_PNMI_ERR_GENERAL;
7728 }
7729 }
7730 else {
7731
7732 RetCode = SK_PNMI_ERR_GENERAL;
7733 }
7734
7735 if (RetCode == SK_PNMI_ERR_OK) {
7736
7737 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7738 }
7739 break;
7740
7741 case SK_DIAG_IDLE:
7742 /* Check if we come from running */
7743 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7744
7745 RetCode = SkDrvLeaveDiagMode(pAC);
7746
7747 }
7748 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7749
7750 RetCode = SK_PNMI_ERR_OK;
7751 }
7752
7753 else {
7754
7755 RetCode = SK_PNMI_ERR_GENERAL;
7756
7757 }
7758
7759 if (RetCode == SK_PNMI_ERR_OK) {
7760
7761 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7762 }
7763 break;
7764
7765 default:
7766 RetCode = SK_PNMI_ERR_BAD_VALUE;
7767 break;
7768 }
7769 break;
7770
7771 default:
7772 RetCode = SK_PNMI_ERR_GENERAL;
7773 }
7774
7775 if (RetCode == SK_PNMI_ERR_OK) {
7776 *pLen = sizeof(SK_U32);
7777 }
7778 else {
7779
7780 *pLen = 0;
7781 }
7782 return (RetCode);
7783}
7784#endif /* SK_DIAG_SUPPORT */
7785
7786/*****************************************************************************
7787 *
7788 * Vct - OID handler function of OIDs
7789 *
7790 * Description:
7791 * The code is simple. No description necessary.
7792 *
7793 * Returns:
7794 * SK_PNMI_ERR_OK The request was performed successfully.
7795 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7796 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7797 * the correct data (e.g. a 32bit value is
7798 * needed, but a 16 bit value was passed).
7799 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7800 * exist (e.g. port instance 3 on a two port
7801 * adapter).
7802 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7803 *
7804 */
7805
7806PNMI_STATIC int Vct(
7807SK_AC *pAC, /* Pointer to adapter context */
7808SK_IOC IoC, /* IO context handle */
7809int Action, /* GET/PRESET/SET action */
7810SK_U32 Id, /* Object ID that is to be processed */
7811char *pBuf, /* Buffer used for the management data transfer */
7812unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7813SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7814unsigned int TableIndex, /* Index to the Id table */
7815SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7816{
7817 SK_GEPORT *pPrt;
7818 SK_PNMI_VCT *pVctBackupData;
7819 SK_U32 LogPortMax;
7820 SK_U32 PhysPortMax;
7821 SK_U32 PhysPortIndex;
7822 SK_U32 Limit;
7823 SK_U32 Offset;
7824 SK_BOOL Link;
7825 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7826 int i;
7827 SK_EVPARA Para;
7828 SK_U32 CableLength;
7829
7830 /*
7831 * Calculate the port indexes from the instance.
7832 */
7833 PhysPortMax = pAC->GIni.GIMacsFound;
7834 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7835
7836 /* Dual net mode? */
7837 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7838 LogPortMax--;
7839 }
7840
7841 if ((Instance != (SK_U32) (-1))) {
7842 /* Check instance range. */
7843 if ((Instance < 2) || (Instance > LogPortMax)) {
7844 *pLen = 0;
7845 return (SK_PNMI_ERR_UNKNOWN_INST);
7846 }
7847
7848 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7849 PhysPortIndex = NetIndex;
7850 }
7851 else {
7852 PhysPortIndex = Instance - 2;
7853 }
7854 Limit = PhysPortIndex + 1;
7855 }
7856 else {
7857 /*
7858 * Instance == (SK_U32) (-1), get all Instances of that OID.
7859 *
7860 * Not implemented yet. May be used in future releases.
7861 */
7862 PhysPortIndex = 0;
7863 Limit = PhysPortMax;
7864 }
7865
7866 pPrt = &pAC->GIni.GP[PhysPortIndex];
7867 if (pPrt->PHWLinkUp) {
7868 Link = SK_TRUE;
7869 }
7870 else {
7871 Link = SK_FALSE;
7872 }
7873
7874 /* Check MAC type */
7875 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
7876 *pLen = 0;
7877 return (SK_PNMI_ERR_GENERAL);
7878 }
7879
7880 /* Initialize backup data pointer. */
7881 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
7882
7883 /* Check action type */
7884 if (Action == SK_PNMI_GET) {
7885 /* Check length */
7886 switch (Id) {
7887
7888 case OID_SKGE_VCT_GET:
7889 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
7890 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
7891 return (SK_PNMI_ERR_TOO_SHORT);
7892 }
7893 break;
7894
7895 case OID_SKGE_VCT_STATUS:
7896 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
7897 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
7898 return (SK_PNMI_ERR_TOO_SHORT);
7899 }
7900 break;
7901
7902 default:
7903 *pLen = 0;
7904 return (SK_PNMI_ERR_GENERAL);
7905 }
7906
7907 /* Get value */
7908 Offset = 0;
7909 for (; PhysPortIndex < Limit; PhysPortIndex++) {
7910 switch (Id) {
7911
7912 case OID_SKGE_VCT_GET:
7913 if ((Link == SK_FALSE) &&
7914 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
7915 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
7916 if (RetCode == 0) {
7917 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
7918 pAC->Pnmi.VctStatus[PhysPortIndex] |=
7919 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
7920
7921 /* Copy results for later use to PNMI struct. */
7922 for (i = 0; i < 4; i++) {
7923 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
7924 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
7925 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
7926 }
7927 }
7928 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
7929 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
7930 }
7931 else {
7932 CableLength = 0;
7933 }
7934 pVctBackupData->PMdiPairLen[i] = CableLength;
7935 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
7936 }
7937
7938 Para.Para32[0] = PhysPortIndex;
7939 Para.Para32[1] = -1;
7940 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
7941 SkEventDispatcher(pAC, IoC);
7942 }
7943 else {
7944 ; /* VCT test is running. */
7945 }
7946 }
7947
7948 /* Get all results. */
7949 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7950 Offset += sizeof(SK_U8);
7951 *(pBuf + Offset) = pPrt->PCableLen;
7952 Offset += sizeof(SK_U8);
7953 for (i = 0; i < 4; i++) {
7954 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
7955 Offset += sizeof(SK_U32);
7956 }
7957 for (i = 0; i < 4; i++) {
7958 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
7959 Offset += sizeof(SK_U8);
7960 }
7961
7962 RetCode = SK_PNMI_ERR_OK;
7963 break;
7964
7965 case OID_SKGE_VCT_STATUS:
7966 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7967 Offset += sizeof(SK_U8);
7968 RetCode = SK_PNMI_ERR_OK;
7969 break;
7970
7971 default:
7972 *pLen = 0;
7973 return (SK_PNMI_ERR_GENERAL);
7974 }
7975 } /* for */
7976 *pLen = Offset;
7977 return (RetCode);
7978
7979 } /* if SK_PNMI_GET */
7980
7981 /*
7982 * From here SET or PRESET action. Check if the passed
7983 * buffer length is plausible.
7984 */
7985
7986 /* Check length */
7987 switch (Id) {
7988 case OID_SKGE_VCT_SET:
7989 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
7990 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
7991 return (SK_PNMI_ERR_TOO_SHORT);
7992 }
7993 break;
7994
7995 default:
7996 *pLen = 0;
7997 return (SK_PNMI_ERR_GENERAL);
7998 }
7999
8000 /*
8001 * Perform preset or set.
8002 */
8003
8004 /* VCT does not support PRESET action. */
8005 if (Action == SK_PNMI_PRESET) {
8006 return (SK_PNMI_ERR_OK);
8007 }
8008
8009 Offset = 0;
8010 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8011 switch (Id) {
8012 case OID_SKGE_VCT_SET: /* Start VCT test. */
8013 if (Link == SK_FALSE) {
8014 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8015
8016 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8017 if (RetCode == 0) { /* RetCode: 0 => Start! */
8018 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8019 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8020 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8021
8022 /*
8023 * Start VCT timer counter.
8024 */
8025 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8026 Para.Para32[0] = PhysPortIndex;
8027 Para.Para32[1] = -1;
8028 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8029 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8030 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8031 RetCode = SK_PNMI_ERR_OK;
8032 }
8033 else { /* RetCode: 2 => Running! */
8034 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8035 RetCode = SK_PNMI_ERR_OK;
8036 }
8037 }
8038 else { /* RetCode: 4 => Link! */
8039 RetCode = 4;
8040 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8041 RetCode = SK_PNMI_ERR_OK;
8042 }
8043 Offset += sizeof(SK_U32);
8044 break;
8045
8046 default:
8047 *pLen = 0;
8048 return (SK_PNMI_ERR_GENERAL);
8049 }
8050 } /* for */
8051 *pLen = Offset;
8052 return (RetCode);
8053
8054} /* Vct */
8055
8056
8057PNMI_STATIC void CheckVctStatus(
8058SK_AC *pAC,
8059SK_IOC IoC,
8060char *pBuf,
8061SK_U32 Offset,
8062SK_U32 PhysPortIndex)
8063{
8064 SK_GEPORT *pPrt;
8065 SK_PNMI_VCT *pVctData;
8066 SK_U32 RetCode;
8067
8068 pPrt = &pAC->GIni.GP[PhysPortIndex];
8069
8070 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8071 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8072
8073 if (!pPrt->PHWLinkUp) {
8074
8075 /* Was a VCT test ever made before? */
8076 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8077 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8078 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8079 }
8080 else {
8081 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8082 }
8083 }
8084
8085 /* Check VCT test status. */
8086 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8087 if (RetCode == 2) { /* VCT test is running. */
8088 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8089 }
8090 else { /* VCT data was copied to pAC here. Check PENDING state. */
8091 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8092 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8093 }
8094 }
8095
8096 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8097 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8098 }
8099 }
8100 else {
8101
8102 /* Was a VCT test ever made before? */
8103 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8104 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8105 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8106 }
8107
8108 /* DSP only valid in 100/1000 modes. */
8109 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8110 SK_LSPEED_STAT_10MBPS) {
8111 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8112 }
8113 }
8114} /* CheckVctStatus */
8115
8116
8117/*****************************************************************************
8118 *
8119 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8120 * PNMI function depending on the subcommand and
8121 * returns all data belonging to the complete database
8122 * or OID request.
8123 *
8124 * Description:
8125 * Looks up the requested subcommand, calls the corresponding handler
8126 * function and passes all required parameters to it.
8127 * The function is called by the driver. It is needed to handle the new
8128 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8129 * the OID and a subcommand to decide what kind of request has to be done.
8130 *
8131 * Returns:
8132 * SK_PNMI_ERR_OK The request was successfully performed
8133 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8134 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8135 * the data.
8136 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8137 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8138 * exist (e.g. port instance 3 on a two port
8139 * adapter.
8140 */
8141int SkPnmiGenIoctl(
8142SK_AC *pAC, /* Pointer to adapter context struct */
8143SK_IOC IoC, /* I/O context */
8144void *pBuf, /* Buffer used for the management data transfer */
8145unsigned int *pLen, /* Length of buffer */
8146SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8147{
8148SK_I32 Mode; /* Store value of subcommand. */
8149SK_U32 Oid; /* Store value of OID. */
8150int ReturnCode; /* Store return value to show status of PNMI action. */
8151int HeaderLength; /* Length of desired action plus OID. */
8152
8153 ReturnCode = SK_PNMI_ERR_GENERAL;
8154
8155 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8156 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8157 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8158 *pLen = *pLen - HeaderLength;
8159 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8160
8161 switch(Mode) {
8162 case SK_GET_SINGLE_VAR:
8163 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8164 (char *) pBuf + sizeof(SK_I32), pLen,
8165 ((SK_U32) (-1)), NetIndex);
8166 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8167 *pLen = *pLen + sizeof(SK_I32);
8168 break;
8169 case SK_PRESET_SINGLE_VAR:
8170 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8171 (char *) pBuf + sizeof(SK_I32), pLen,
8172 ((SK_U32) (-1)), NetIndex);
8173 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8174 *pLen = *pLen + sizeof(SK_I32);
8175 break;
8176 case SK_SET_SINGLE_VAR:
8177 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8178 (char *) pBuf + sizeof(SK_I32), pLen,
8179 ((SK_U32) (-1)), NetIndex);
8180 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8181 *pLen = *pLen + sizeof(SK_I32);
8182 break;
8183 case SK_GET_FULL_MIB:
8184 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8185 break;
8186 case SK_PRESET_FULL_MIB:
8187 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8188 break;
8189 case SK_SET_FULL_MIB:
8190 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8191 break;
8192 default:
8193 break;
8194 }
8195
8196 return (ReturnCode);
8197
8198} /* SkGeIocGen */
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
deleted file mode 100644
index e5ee6d63ba4e..000000000000
--- a/drivers/net/sk98lin/skgesirq.c
+++ /dev/null
@@ -1,2229 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgesirq.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.92 $
6 * Date: $Date: 2003/09/16 14:37:07 $
7 * Purpose: Special IRQ module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * Special Interrupt handler
27 *
28 * The following abstract should show how this module is included
29 * in the driver path:
30 *
31 * In the ISR of the driver the bits for frame transmission complete and
32 * for receive complete are checked and handled by the driver itself.
33 * The bits of the slow path mask are checked after that and then the
34 * entry into the so-called "slow path" is prepared. It is an implementors
35 * decision whether this is executed directly or just scheduled by
36 * disabling the mask. In the interrupt service routine some events may be
37 * generated, so it would be a good idea to call the EventDispatcher
38 * right after this ISR.
39 *
40 * The Interrupt source register of the adapter is NOT read by this module.
41 * SO if the drivers implementor needs a while loop around the
42 * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
43 * each loop entered.
44 *
45 * However, the MAC Interrupt status registers are read in a while loop.
46 *
47 */
48
49#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
50static const char SysKonnectFileId[] =
51 "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
52#endif
53
54#include "h/skdrv1st.h" /* Driver Specific Definitions */
55#ifndef SK_SLIM
56#include "h/skgepnmi.h" /* PNMI Definitions */
57#include "h/skrlmt.h" /* RLMT Definitions */
58#endif
59#include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */
60
61/* local function prototypes */
62#ifdef GENESIS
63static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
64static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL);
65static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
66#endif /* GENESIS */
67#ifdef YUKON
68static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL);
69static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
70#endif /* YUKON */
71#ifdef OTHER_PHY
72static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL);
73static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL);
74static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
75#endif /* OTHER_PHY */
76
77#ifdef GENESIS
78/*
79 * array of Rx counter from XMAC which are checked
80 * in AutoSense mode to check whether a link is not able to auto-negotiate.
81 */
82static const SK_U16 SkGeRxRegs[]= {
83 XM_RXF_64B,
84 XM_RXF_127B,
85 XM_RXF_255B,
86 XM_RXF_511B,
87 XM_RXF_1023B,
88 XM_RXF_MAX_SZ
89} ;
90#endif /* GENESIS */
91
92#ifdef __C2MAN__
93/*
94 * Special IRQ function
95 *
96 * General Description:
97 *
98 */
99intro()
100{}
101#endif
102
103/******************************************************************************
104 *
105 * SkHWInitDefSense() - Default Autosensing mode initialization
106 *
107 * Description: sets the PLinkMode for HWInit
108 *
109 * Returns: N/A
110 */
111static void SkHWInitDefSense(
112SK_AC *pAC, /* adapter context */
113SK_IOC IoC, /* IO context */
114int Port) /* Port Index (MAC_1 + n) */
115{
116 SK_GEPORT *pPrt; /* GIni Port struct pointer */
117
118 pPrt = &pAC->GIni.GP[Port];
119
120 pPrt->PAutoNegTimeOut = 0;
121
122 if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
123 pPrt->PLinkMode = pPrt->PLinkModeConf;
124 return;
125 }
126
127 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
128 ("AutoSensing: First mode %d on Port %d\n",
129 (int)SK_LMODE_AUTOFULL, Port));
130
131 pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
132
133 return;
134} /* SkHWInitDefSense */
135
136
137#ifdef GENESIS
138/******************************************************************************
139 *
140 * SkHWSenseGetNext() - Get Next Autosensing Mode
141 *
142 * Description: gets the appropriate next mode
143 *
144 * Note:
145 *
146 */
147static SK_U8 SkHWSenseGetNext(
148SK_AC *pAC, /* adapter context */
149SK_IOC IoC, /* IO context */
150int Port) /* Port Index (MAC_1 + n) */
151{
152 SK_GEPORT *pPrt; /* GIni Port struct pointer */
153
154 pPrt = &pAC->GIni.GP[Port];
155
156 pPrt->PAutoNegTimeOut = 0;
157
158 if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
159 /* Leave all as configured */
160 return(pPrt->PLinkModeConf);
161 }
162
163 if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
164 /* Return next mode AUTOBOTH */
165 return ((SK_U8)SK_LMODE_AUTOBOTH);
166 }
167
168 /* Return default autofull */
169 return ((SK_U8)SK_LMODE_AUTOFULL);
170} /* SkHWSenseGetNext */
171
172
173/******************************************************************************
174 *
175 * SkHWSenseSetNext() - Autosensing Set next mode
176 *
177 * Description: sets the appropriate next mode
178 *
179 * Returns: N/A
180 */
181static void SkHWSenseSetNext(
182SK_AC *pAC, /* adapter context */
183SK_IOC IoC, /* IO context */
184int Port, /* Port Index (MAC_1 + n) */
185SK_U8 NewMode) /* New Mode to be written in sense mode */
186{
187 SK_GEPORT *pPrt; /* GIni Port struct pointer */
188
189 pPrt = &pAC->GIni.GP[Port];
190
191 pPrt->PAutoNegTimeOut = 0;
192
193 if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
194 return;
195 }
196
197 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
198 ("AutoSensing: next mode %d on Port %d\n",
199 (int)NewMode, Port));
200
201 pPrt->PLinkMode = NewMode;
202
203 return;
204} /* SkHWSenseSetNext */
205#endif /* GENESIS */
206
207
208/******************************************************************************
209 *
210 * SkHWLinkDown() - Link Down handling
211 *
212 * Description: handles the hardware link down signal
213 *
214 * Returns: N/A
215 */
216void SkHWLinkDown(
217SK_AC *pAC, /* adapter context */
218SK_IOC IoC, /* IO context */
219int Port) /* Port Index (MAC_1 + n) */
220{
221 SK_GEPORT *pPrt; /* GIni Port struct pointer */
222
223 pPrt = &pAC->GIni.GP[Port];
224
225 /* Disable all MAC interrupts */
226 SkMacIrqDisable(pAC, IoC, Port);
227
228 /* Disable Receiver and Transmitter */
229 SkMacRxTxDisable(pAC, IoC, Port);
230
231 /* Init default sense mode */
232 SkHWInitDefSense(pAC, IoC, Port);
233
234 if (pPrt->PHWLinkUp == SK_FALSE) {
235 return;
236 }
237
238 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
239 ("Link down Port %d\n", Port));
240
241 /* Set Link to DOWN */
242 pPrt->PHWLinkUp = SK_FALSE;
243
244 /* Reset Port stati */
245 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
246 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
247 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
248
249 /* Re-init Phy especially when the AutoSense default is set now */
250 SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
251
252 /* GP0: used for workaround of Rev. C Errata 2 */
253
254 /* Do NOT signal to RLMT */
255
256 /* Do NOT start the timer here */
257} /* SkHWLinkDown */
258
259
260/******************************************************************************
261 *
262 * SkHWLinkUp() - Link Up handling
263 *
264 * Description: handles the hardware link up signal
265 *
266 * Returns: N/A
267 */
268static void SkHWLinkUp(
269SK_AC *pAC, /* adapter context */
270SK_IOC IoC, /* IO context */
271int Port) /* Port Index (MAC_1 + n) */
272{
273 SK_GEPORT *pPrt; /* GIni Port struct pointer */
274
275 pPrt = &pAC->GIni.GP[Port];
276
277 if (pPrt->PHWLinkUp) {
278 /* We do NOT need to proceed on active link */
279 return;
280 }
281
282 pPrt->PHWLinkUp = SK_TRUE;
283 pPrt->PAutoNegFail = SK_FALSE;
284 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
285
286 if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
287 pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
288 pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
289 /* Link is up and no Auto-negotiation should be done */
290
291 /* Link speed should be the configured one */
292 switch (pPrt->PLinkSpeed) {
293 case SK_LSPEED_AUTO:
294 /* default is 1000 Mbps */
295 case SK_LSPEED_1000MBPS:
296 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
297 break;
298 case SK_LSPEED_100MBPS:
299 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
300 break;
301 case SK_LSPEED_10MBPS:
302 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
303 break;
304 }
305
306 /* Set Link Mode Status */
307 if (pPrt->PLinkMode == SK_LMODE_FULL) {
308 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
309 }
310 else {
311 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
312 }
313
314 /* No flow control without auto-negotiation */
315 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
316
317 /* enable Rx/Tx */
318 (void)SkMacRxTxEnable(pAC, IoC, Port);
319 }
320} /* SkHWLinkUp */
321
322
323/******************************************************************************
324 *
325 * SkMacParity() - MAC parity workaround
326 *
327 * Description: handles MAC parity errors correctly
328 *
329 * Returns: N/A
330 */
331static void SkMacParity(
332SK_AC *pAC, /* adapter context */
333SK_IOC IoC, /* IO context */
334int Port) /* Port Index of the port failed */
335{
336 SK_EVPARA Para;
337 SK_GEPORT *pPrt; /* GIni Port struct pointer */
338 SK_U32 TxMax; /* Tx Max Size Counter */
339
340 pPrt = &pAC->GIni.GP[Port];
341
342 /* Clear IRQ Tx Parity Error */
343#ifdef GENESIS
344 if (pAC->GIni.GIGenesis) {
345
346 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
347 }
348#endif /* GENESIS */
349
350#ifdef YUKON
351 if (pAC->GIni.GIYukon) {
352 /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
353 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
354 (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON &&
355 pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
356 }
357#endif /* YUKON */
358
359 if (pPrt->PCheckPar) {
360
361 if (Port == MAC_1) {
362 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
363 }
364 else {
365 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
366 }
367 Para.Para64 = Port;
368 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
369
370 Para.Para32[0] = Port;
371 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
372
373 return;
374 }
375
376 /* Check whether frames with a size of 1k were sent */
377#ifdef GENESIS
378 if (pAC->GIni.GIGenesis) {
379 /* Snap statistic counters */
380 (void)SkXmUpdateStats(pAC, IoC, Port);
381
382 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
383 }
384#endif /* GENESIS */
385
386#ifdef YUKON
387 if (pAC->GIni.GIYukon) {
388
389 (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
390 }
391#endif /* YUKON */
392
393 if (TxMax > 0) {
394 /* From now on check the parity */
395 pPrt->PCheckPar = SK_TRUE;
396 }
397} /* SkMacParity */
398
399
400/******************************************************************************
401 *
402 * SkGeHwErr() - Hardware Error service routine
403 *
404 * Description: handles all HW Error interrupts
405 *
406 * Returns: N/A
407 */
408static void SkGeHwErr(
409SK_AC *pAC, /* adapter context */
410SK_IOC IoC, /* IO context */
411SK_U32 HwStatus) /* Interrupt status word */
412{
413 SK_EVPARA Para;
414 SK_U16 Word;
415
416 if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
417 /* PCI Errors occured */
418 if ((HwStatus & IS_IRQ_STAT) != 0) {
419 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
420 }
421 else {
422 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
423 }
424
425 /* Reset all bits in the PCI STATUS register */
426 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
427
428 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
429 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
430 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
431
432 Para.Para64 = 0;
433 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
434 }
435
436#ifdef GENESIS
437 if (pAC->GIni.GIGenesis) {
438
439 if ((HwStatus & IS_NO_STAT_M1) != 0) {
440 /* Ignore it */
441 /* This situation is also indicated in the descriptor */
442 SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
443 }
444
445 if ((HwStatus & IS_NO_STAT_M2) != 0) {
446 /* Ignore it */
447 /* This situation is also indicated in the descriptor */
448 SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
449 }
450
451 if ((HwStatus & IS_NO_TIST_M1) != 0) {
452 /* Ignore it */
453 /* This situation is also indicated in the descriptor */
454 SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
455 }
456
457 if ((HwStatus & IS_NO_TIST_M2) != 0) {
458 /* Ignore it */
459 /* This situation is also indicated in the descriptor */
460 SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
461 }
462 }
463#endif /* GENESIS */
464
465#ifdef YUKON
466 if (pAC->GIni.GIYukon) {
467 /* This is necessary only for Rx timing measurements */
468 if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
469 /* increment Time Stamp Timer counter (high) */
470 pAC->GIni.GITimeStampCnt++;
471
472 /* Clear Time Stamp Timer IRQ */
473 SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
474 }
475
476 if ((HwStatus & IS_IRQ_SENSOR) != 0) {
477 /* no sensors on 32-bit Yukon */
478 if (pAC->GIni.GIYukon32Bit) {
479 /* disable HW Error IRQ */
480 pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
481 }
482 }
483 }
484#endif /* YUKON */
485
486 if ((HwStatus & IS_RAM_RD_PAR) != 0) {
487 SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
488 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
489 Para.Para64 = 0;
490 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
491 }
492
493 if ((HwStatus & IS_RAM_WR_PAR) != 0) {
494 SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
495 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
496 Para.Para64 = 0;
497 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
498 }
499
500 if ((HwStatus & IS_M1_PAR_ERR) != 0) {
501 SkMacParity(pAC, IoC, MAC_1);
502 }
503
504 if ((HwStatus & IS_M2_PAR_ERR) != 0) {
505 SkMacParity(pAC, IoC, MAC_2);
506 }
507
508 if ((HwStatus & IS_R1_PAR_ERR) != 0) {
509 /* Clear IRQ */
510 SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
511
512 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
513 Para.Para64 = MAC_1;
514 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
515
516 Para.Para32[0] = MAC_1;
517 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
518 }
519
520 if ((HwStatus & IS_R2_PAR_ERR) != 0) {
521 /* Clear IRQ */
522 SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
523
524 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
525 Para.Para64 = MAC_2;
526 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
527
528 Para.Para32[0] = MAC_2;
529 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
530 }
531} /* SkGeHwErr */
532
533
534/******************************************************************************
535 *
536 * SkGeSirqIsr() - Special Interrupt Service Routine
537 *
538 * Description: handles all non data transfer specific interrupts (slow path)
539 *
540 * Returns: N/A
541 */
542void SkGeSirqIsr(
543SK_AC *pAC, /* adapter context */
544SK_IOC IoC, /* IO context */
545SK_U32 Istatus) /* Interrupt status word */
546{
547 SK_EVPARA Para;
548 SK_U32 RegVal32; /* Read register value */
549 SK_GEPORT *pPrt; /* GIni Port struct pointer */
550 SK_U16 PhyInt;
551 int i;
552
553 if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
554 /* read the HW Error Interrupt source */
555 SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
556
557 SkGeHwErr(pAC, IoC, RegVal32);
558 }
559
560 /*
561 * Packet Timeout interrupts
562 */
563 /* Check whether MACs are correctly initialized */
564 if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
565 pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
566 /* MAC 1 was not initialized but Packet timeout occured */
567 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
568 SKERR_SIRQ_E004MSG);
569 }
570
571 if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
572 pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
573 /* MAC 2 was not initialized but Packet timeout occured */
574 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
575 SKERR_SIRQ_E005MSG);
576 }
577
578 if ((Istatus & IS_PA_TO_RX1) != 0) {
579 /* Means network is filling us up */
580 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
581 SKERR_SIRQ_E002MSG);
582 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
583 }
584
585 if ((Istatus & IS_PA_TO_RX2) != 0) {
586 /* Means network is filling us up */
587 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
588 SKERR_SIRQ_E003MSG);
589 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
590 }
591
592 if ((Istatus & IS_PA_TO_TX1) != 0) {
593
594 pPrt = &pAC->GIni.GP[0];
595
596 /* May be a normal situation in a server with a slow network */
597 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
598
599#ifdef GENESIS
600 if (pAC->GIni.GIGenesis) {
601 /*
602 * workaround: if in half duplex mode, check for Tx hangup.
603 * Read number of TX'ed bytes, wait for 10 ms, then compare
604 * the number with current value. If nothing changed, we assume
605 * that Tx is hanging and do a FIFO flush (see event routine).
606 */
607 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
608 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
609 !pPrt->HalfDupTimerActive) {
610 /*
611 * many more pack. arb. timeouts may come in between,
612 * we ignore those
613 */
614 pPrt->HalfDupTimerActive = SK_TRUE;
615 /* Snap statistic counters */
616 (void)SkXmUpdateStats(pAC, IoC, 0);
617
618 (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
619
620 pPrt->LastOctets = (SK_U64)RegVal32 << 32;
621
622 (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
623
624 pPrt->LastOctets += RegVal32;
625
626 Para.Para32[0] = 0;
627 SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
628 SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
629 }
630 }
631#endif /* GENESIS */
632 }
633
634 if ((Istatus & IS_PA_TO_TX2) != 0) {
635
636 pPrt = &pAC->GIni.GP[1];
637
638 /* May be a normal situation in a server with a slow network */
639 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
640
641#ifdef GENESIS
642 if (pAC->GIni.GIGenesis) {
643 /* workaround: see above */
644 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
645 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
646 !pPrt->HalfDupTimerActive) {
647 pPrt->HalfDupTimerActive = SK_TRUE;
648 /* Snap statistic counters */
649 (void)SkXmUpdateStats(pAC, IoC, 1);
650
651 (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
652
653 pPrt->LastOctets = (SK_U64)RegVal32 << 32;
654
655 (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
656
657 pPrt->LastOctets += RegVal32;
658
659 Para.Para32[0] = 1;
660 SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
661 SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
662 }
663 }
664#endif /* GENESIS */
665 }
666
667 /* Check interrupts of the particular queues */
668 if ((Istatus & IS_R1_C) != 0) {
669 /* Clear IRQ */
670 SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
671 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
672 SKERR_SIRQ_E006MSG);
673 Para.Para64 = MAC_1;
674 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
675 Para.Para32[0] = MAC_1;
676 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
677 }
678
679 if ((Istatus & IS_R2_C) != 0) {
680 /* Clear IRQ */
681 SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
682 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
683 SKERR_SIRQ_E007MSG);
684 Para.Para64 = MAC_2;
685 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
686 Para.Para32[0] = MAC_2;
687 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
688 }
689
690 if ((Istatus & IS_XS1_C) != 0) {
691 /* Clear IRQ */
692 SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
693 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
694 SKERR_SIRQ_E008MSG);
695 Para.Para64 = MAC_1;
696 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
697 Para.Para32[0] = MAC_1;
698 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
699 }
700
701 if ((Istatus & IS_XA1_C) != 0) {
702 /* Clear IRQ */
703 SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
704 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
705 SKERR_SIRQ_E009MSG);
706 Para.Para64 = MAC_1;
707 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
708 Para.Para32[0] = MAC_1;
709 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
710 }
711
712 if ((Istatus & IS_XS2_C) != 0) {
713 /* Clear IRQ */
714 SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
715 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
716 SKERR_SIRQ_E010MSG);
717 Para.Para64 = MAC_2;
718 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
719 Para.Para32[0] = MAC_2;
720 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
721 }
722
723 if ((Istatus & IS_XA2_C) != 0) {
724 /* Clear IRQ */
725 SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
726 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
727 SKERR_SIRQ_E011MSG);
728 Para.Para64 = MAC_2;
729 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
730 Para.Para32[0] = MAC_2;
731 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
732 }
733
734 /* External reg interrupt */
735 if ((Istatus & IS_EXT_REG) != 0) {
736 /* Test IRQs from PHY */
737 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
738
739 pPrt = &pAC->GIni.GP[i];
740
741 if (pPrt->PState == SK_PRT_RESET) {
742 continue;
743 }
744
745#ifdef GENESIS
746 if (pAC->GIni.GIGenesis) {
747
748 switch (pPrt->PhyType) {
749
750 case SK_PHY_XMAC:
751 break;
752
753 case SK_PHY_BCOM:
754 SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
755
756 if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
757 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
758 ("Port %d Bcom Int: 0x%04X\n",
759 i, PhyInt));
760 SkPhyIsrBcom(pAC, IoC, i, PhyInt);
761 }
762 break;
763#ifdef OTHER_PHY
764 case SK_PHY_LONE:
765 SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
766
767 if ((PhyInt & PHY_L_DEF_MSK) != 0) {
768 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
769 ("Port %d Lone Int: %x\n",
770 i, PhyInt));
771 SkPhyIsrLone(pAC, IoC, i, PhyInt);
772 }
773 break;
774#endif /* OTHER_PHY */
775 }
776 }
777#endif /* GENESIS */
778
779#ifdef YUKON
780 if (pAC->GIni.GIYukon) {
781 /* Read PHY Interrupt Status */
782 SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
783
784 if ((PhyInt & PHY_M_DEF_MSK) != 0) {
785 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
786 ("Port %d Marv Int: 0x%04X\n",
787 i, PhyInt));
788 SkPhyIsrGmac(pAC, IoC, i, PhyInt);
789 }
790 }
791#endif /* YUKON */
792 }
793 }
794
795 /* I2C Ready interrupt */
796 if ((Istatus & IS_I2C_READY) != 0) {
797#ifdef SK_SLIM
798 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
799#else
800 SkI2cIsr(pAC, IoC);
801#endif
802 }
803
804 /* SW forced interrupt */
805 if ((Istatus & IS_IRQ_SW) != 0) {
806 /* clear the software IRQ */
807 SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
808 }
809
810 if ((Istatus & IS_LNK_SYNC_M1) != 0) {
811 /*
812 * We do NOT need the Link Sync interrupt, because it shows
813 * us only a link going down.
814 */
815 /* clear interrupt */
816 SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
817 }
818
819 /* Check MAC after link sync counter */
820 if ((Istatus & IS_MAC1) != 0) {
821 /* IRQ from MAC 1 */
822 SkMacIrq(pAC, IoC, MAC_1);
823 }
824
825 if ((Istatus & IS_LNK_SYNC_M2) != 0) {
826 /*
827 * We do NOT need the Link Sync interrupt, because it shows
828 * us only a link going down.
829 */
830 /* clear interrupt */
831 SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
832 }
833
834 /* Check MAC after link sync counter */
835 if ((Istatus & IS_MAC2) != 0) {
836 /* IRQ from MAC 2 */
837 SkMacIrq(pAC, IoC, MAC_2);
838 }
839
840 /* Timer interrupt (served last) */
841 if ((Istatus & IS_TIMINT) != 0) {
842 /* check for HW Errors */
843 if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {
844 /* read the HW Error Interrupt source */
845 SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
846
847 SkGeHwErr(pAC, IoC, RegVal32);
848 }
849
850 SkHwtIsr(pAC, IoC);
851 }
852
853} /* SkGeSirqIsr */
854
855
856#ifdef GENESIS
857/******************************************************************************
858 *
859 * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
860 *
861 * return:
862 * 0 o.k. nothing needed
863 * 1 Restart needed on this port
864 */
865static int SkGePortCheckShorts(
866SK_AC *pAC, /* Adapter Context */
867SK_IOC IoC, /* IO Context */
868int Port) /* Which port should be checked */
869{
870 SK_U32 Shorts; /* Short Event Counter */
871 SK_U32 CheckShorts; /* Check value for Short Event Counter */
872 SK_U64 RxCts; /* Rx Counter (packets on network) */
873 SK_U32 RxTmp; /* Rx temp. Counter */
874 SK_U32 FcsErrCts; /* FCS Error Counter */
875 SK_GEPORT *pPrt; /* GIni Port struct pointer */
876 int Rtv; /* Return value */
877 int i;
878
879 pPrt = &pAC->GIni.GP[Port];
880
881 /* Default: no action */
882 Rtv = SK_HW_PS_NONE;
883
884 (void)SkXmUpdateStats(pAC, IoC, Port);
885
886 /* Extra precaution: check for short Event counter */
887 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
888
889 /*
890 * Read Rx counters (packets seen on the network and not necessarily
891 * really received.
892 */
893 RxCts = 0;
894
895 for (i = 0; i < ARRAY_SIZE(SkGeRxRegs); i++) {
896
897 (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
898
899 RxCts += (SK_U64)RxTmp;
900 }
901
902 /* On default: check shorts against zero */
903 CheckShorts = 0;
904
905 /* Extra precaution on active links */
906 if (pPrt->PHWLinkUp) {
907 /* Reset Link Restart counter */
908 pPrt->PLinkResCt = 0;
909 pPrt->PAutoNegTOCt = 0;
910
911 /* If link is up check for 2 */
912 CheckShorts = 2;
913
914 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
915
916 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
917 pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
918 (pPrt->PLinkMode == SK_LMODE_HALF ||
919 pPrt->PLinkMode == SK_LMODE_FULL)) {
920 /*
921 * This is autosensing and we are in the fallback
922 * manual full/half duplex mode.
923 */
924 if (RxCts == pPrt->PPrevRx) {
925 /* Nothing received, restart link */
926 pPrt->PPrevFcs = FcsErrCts;
927 pPrt->PPrevShorts = Shorts;
928
929 return(SK_HW_PS_RESTART);
930 }
931 else {
932 pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
933 }
934 }
935
936 if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
937 (!(FcsErrCts - pPrt->PPrevFcs))) {
938 /*
939 * Note: The compare with zero above has to be done the way shown,
940 * otherwise the Linux driver will have a problem.
941 */
942 /*
943 * We received a bunch of frames or no CRC error occured on the
944 * network -> ok.
945 */
946 pPrt->PPrevRx = RxCts;
947 pPrt->PPrevFcs = FcsErrCts;
948 pPrt->PPrevShorts = Shorts;
949
950 return(SK_HW_PS_NONE);
951 }
952
953 pPrt->PPrevFcs = FcsErrCts;
954 }
955
956
957 if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
958 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
959 ("Short Event Count Restart Port %d \n", Port));
960 Rtv = SK_HW_PS_RESTART;
961 }
962
963 pPrt->PPrevShorts = Shorts;
964 pPrt->PPrevRx = RxCts;
965
966 return(Rtv);
967} /* SkGePortCheckShorts */
968#endif /* GENESIS */
969
970
971/******************************************************************************
972 *
973 * SkGePortCheckUp() - Check if the link is up
974 *
975 * return:
976 * 0 o.k. nothing needed
977 * 1 Restart needed on this port
978 * 2 Link came up
979 */
980static int SkGePortCheckUp(
981SK_AC *pAC, /* Adapter Context */
982SK_IOC IoC, /* IO Context */
983int Port) /* Which port should be checked */
984{
985 SK_GEPORT *pPrt; /* GIni Port struct pointer */
986 SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
987 int Rtv; /* Return value */
988
989 Rtv = SK_HW_PS_NONE;
990
991 pPrt = &pAC->GIni.GP[Port];
992
993 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
994 AutoNeg = SK_FALSE;
995 }
996 else {
997 AutoNeg = SK_TRUE;
998 }
999
1000#ifdef GENESIS
1001 if (pAC->GIni.GIGenesis) {
1002
1003 switch (pPrt->PhyType) {
1004
1005 case SK_PHY_XMAC:
1006 Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
1007 break;
1008 case SK_PHY_BCOM:
1009 Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg);
1010 break;
1011#ifdef OTHER_PHY
1012 case SK_PHY_LONE:
1013 Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg);
1014 break;
1015 case SK_PHY_NAT:
1016 Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg);
1017 break;
1018#endif /* OTHER_PHY */
1019 }
1020 }
1021#endif /* GENESIS */
1022
1023#ifdef YUKON
1024 if (pAC->GIni.GIYukon) {
1025
1026 Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
1027 }
1028#endif /* YUKON */
1029
1030 return(Rtv);
1031} /* SkGePortCheckUp */
1032
1033
1034#ifdef GENESIS
1035/******************************************************************************
1036 *
1037 * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
1038 *
1039 * return:
1040 * 0 o.k. nothing needed
1041 * 1 Restart needed on this port
1042 * 2 Link came up
1043 */
1044static int SkGePortCheckUpXmac(
1045SK_AC *pAC, /* Adapter Context */
1046SK_IOC IoC, /* IO Context */
1047int Port, /* Which port should be checked */
1048SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1049{
1050 SK_U32 Shorts; /* Short Event Counter */
1051 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1052 int Done;
1053 SK_U32 GpReg; /* General Purpose register value */
1054 SK_U16 Isrc; /* Interrupt source register */
1055 SK_U16 IsrcSum; /* Interrupt source register sum */
1056 SK_U16 LpAb; /* Link Partner Ability */
1057 SK_U16 ResAb; /* Resolved Ability */
1058 SK_U16 ExtStat; /* Extended Status Register */
1059 SK_U8 NextMode; /* Next AutoSensing Mode */
1060
1061 pPrt = &pAC->GIni.GP[Port];
1062
1063 if (pPrt->PHWLinkUp) {
1064 if (pPrt->PhyType != SK_PHY_XMAC) {
1065 return(SK_HW_PS_NONE);
1066 }
1067 else {
1068 return(SkGePortCheckShorts(pAC, IoC, Port));
1069 }
1070 }
1071
1072 IsrcSum = pPrt->PIsave;
1073 pPrt->PIsave = 0;
1074
1075 /* Now wait for each port's link */
1076 if (pPrt->PLinkBroken) {
1077 /* Link was broken */
1078 XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
1079
1080 if ((GpReg & XM_GP_INP_ASS) == 0) {
1081 /* The Link is in sync */
1082 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1083 IsrcSum |= Isrc;
1084 SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
1085
1086 if ((Isrc & XM_IS_INP_ASS) == 0) {
1087 /* It has been in sync since last time */
1088 /* Restart the PORT */
1089 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1090 ("Link in sync Restart Port %d\n", Port));
1091
1092 (void)SkXmUpdateStats(pAC, IoC, Port);
1093
1094 /* We now need to reinitialize the PrevShorts counter */
1095 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
1096 pPrt->PPrevShorts = Shorts;
1097
1098 pPrt->PLinkBroken = SK_FALSE;
1099
1100 /*
1101 * Link Restart Workaround:
1102 * it may be possible that the other Link side
1103 * restarts its link as well an we detect
1104 * another LinkBroken. To prevent this
1105 * happening we check for a maximum number
1106 * of consecutive restart. If those happens,
1107 * we do NOT restart the active link and
1108 * check whether the link is now o.k.
1109 */
1110 pPrt->PLinkResCt++;
1111
1112 pPrt->PAutoNegTimeOut = 0;
1113
1114 if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
1115 return(SK_HW_PS_RESTART);
1116 }
1117
1118 pPrt->PLinkResCt = 0;
1119
1120 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1121 ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
1122 }
1123 else {
1124 pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
1125
1126 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1127 ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
1128
1129 /* Do nothing more if link is broken */
1130 return(SK_HW_PS_NONE);
1131 }
1132 }
1133 else {
1134 /* Do nothing more if link is broken */
1135 return(SK_HW_PS_NONE);
1136 }
1137
1138 }
1139 else {
1140 /* Link was not broken, check if it is */
1141 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1142 IsrcSum |= Isrc;
1143 if ((Isrc & XM_IS_INP_ASS) != 0) {
1144 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1145 IsrcSum |= Isrc;
1146 if ((Isrc & XM_IS_INP_ASS) != 0) {
1147 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1148 IsrcSum |= Isrc;
1149 if ((Isrc & XM_IS_INP_ASS) != 0) {
1150 pPrt->PLinkBroken = SK_TRUE;
1151 /* Re-Init Link partner Autoneg flag */
1152 pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
1153 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1154 ("Link broken Port %d\n", Port));
1155
1156 /* Cable removed-> reinit sense mode */
1157 SkHWInitDefSense(pAC, IoC, Port);
1158
1159 return(SK_HW_PS_RESTART);
1160 }
1161 }
1162 }
1163 else {
1164 SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
1165
1166 if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
1167 return(SK_HW_PS_RESTART);
1168 }
1169 }
1170 }
1171
1172 /*
1173 * here we usually can check whether the link is in sync and
1174 * auto-negotiation is done.
1175 */
1176 XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
1177 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1178 IsrcSum |= Isrc;
1179
1180 SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
1181
1182 if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
1183 if ((GpReg & XM_GP_INP_ASS) == 0) {
1184 /* Save Auto-negotiation Done interrupt only if link is in sync */
1185 pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
1186 }
1187#ifdef DEBUG
1188 if ((pPrt->PIsave & XM_IS_AND) != 0) {
1189 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1190 ("AutoNeg done rescheduled Port %d\n", Port));
1191 }
1192#endif /* DEBUG */
1193 return(SK_HW_PS_NONE);
1194 }
1195
1196 if (AutoNeg) {
1197 if ((IsrcSum & XM_IS_AND) != 0) {
1198 SkHWLinkUp(pAC, IoC, Port);
1199 Done = SkMacAutoNegDone(pAC, IoC, Port);
1200 if (Done != SK_AND_OK) {
1201 /* Get PHY parameters, for debugging only */
1202 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
1203 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
1204 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1205 ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
1206 Port, LpAb, ResAb));
1207
1208 /* Try next possible mode */
1209 NextMode = SkHWSenseGetNext(pAC, IoC, Port);
1210 SkHWLinkDown(pAC, IoC, Port);
1211 if (Done == SK_AND_DUP_CAP) {
1212 /* GoTo next mode */
1213 SkHWSenseSetNext(pAC, IoC, Port, NextMode);
1214 }
1215
1216 return(SK_HW_PS_RESTART);
1217 }
1218 /*
1219 * Dummy Read extended status to prevent extra link down/ups
1220 * (clear Page Received bit if set)
1221 */
1222 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
1223
1224 return(SK_HW_PS_LINK);
1225 }
1226
1227 /* AutoNeg not done, but HW link is up. Check for timeouts */
1228 pPrt->PAutoNegTimeOut++;
1229 if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
1230 /* Increase the Timeout counter */
1231 pPrt->PAutoNegTOCt++;
1232
1233 /* Timeout occured */
1234 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1235 ("AutoNeg timeout Port %d\n", Port));
1236 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1237 pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
1238 /* Set Link manually up */
1239 SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
1240 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1241 ("Set manual full duplex Port %d\n", Port));
1242 }
1243
1244 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1245 pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
1246 pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
1247 /*
1248 * This is rather complicated.
1249 * we need to check here whether the LIPA_AUTO
1250 * we saw before is false alert. We saw at one
1251 * switch ( SR8800) that on boot time it sends
1252 * just one auto-neg packet and does no further
1253 * auto-negotiation.
1254 * Solution: we restart the autosensing after
1255 * a few timeouts.
1256 */
1257 pPrt->PAutoNegTOCt = 0;
1258 pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
1259 SkHWInitDefSense(pAC, IoC, Port);
1260 }
1261
1262 /* Do the restart */
1263 return(SK_HW_PS_RESTART);
1264 }
1265 }
1266 else {
1267 /* Link is up and we don't need more */
1268#ifdef DEBUG
1269 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1270 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1271 ("ERROR: Lipa auto detected on port %d\n", Port));
1272 }
1273#endif /* DEBUG */
1274 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1275 ("Link sync(GP), Port %d\n", Port));
1276 SkHWLinkUp(pAC, IoC, Port);
1277
1278 /*
1279 * Link sync (GP) and so assume a good connection. But if not received
1280 * a bunch of frames received in a time slot (maybe broken tx cable)
1281 * the port is restart.
1282 */
1283 return(SK_HW_PS_LINK);
1284 }
1285
1286 return(SK_HW_PS_NONE);
1287} /* SkGePortCheckUpXmac */
1288
1289
1290/******************************************************************************
1291 *
1292 * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
1293 *
1294 * return:
1295 * 0 o.k. nothing needed
1296 * 1 Restart needed on this port
1297 * 2 Link came up
1298 */
1299static int SkGePortCheckUpBcom(
1300SK_AC *pAC, /* Adapter Context */
1301SK_IOC IoC, /* IO Context */
1302int Port, /* Which port should be checked */
1303SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1304{
1305 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1306 int Done;
1307 SK_U16 Isrc; /* Interrupt source register */
1308 SK_U16 PhyStat; /* Phy Status Register */
1309 SK_U16 ResAb; /* Master/Slave resolution */
1310 SK_U16 Ctrl; /* Broadcom control flags */
1311#ifdef DEBUG
1312 SK_U16 LpAb;
1313 SK_U16 ExtStat;
1314#endif /* DEBUG */
1315
1316 pPrt = &pAC->GIni.GP[Port];
1317
1318 /* Check for No HCD Link events (#10523) */
1319 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
1320
1321#ifdef xDEBUG
1322 if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) ==
1323 (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
1324
1325 SK_U32 Stat1, Stat2, Stat3;
1326
1327 Stat1 = 0;
1328 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
1329 CMSMPrintString(
1330 pAC->pConfigTable,
1331 MSG_TYPE_RUNTIME_INFO,
1332 "CheckUp1 - Stat: %x, Mask: %x",
1333 (void *)Isrc,
1334 (void *)Stat1);
1335
1336 Stat1 = 0;
1337 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
1338 Stat2 = 0;
1339 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
1340 Stat1 = Stat1 << 16 | Stat2;
1341 Stat2 = 0;
1342 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
1343 Stat3 = 0;
1344 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
1345 Stat2 = Stat2 << 16 | Stat3;
1346 CMSMPrintString(
1347 pAC->pConfigTable,
1348 MSG_TYPE_RUNTIME_INFO,
1349 "Ctrl/Stat: %x, AN Adv/LP: %x",
1350 (void *)Stat1,
1351 (void *)Stat2);
1352
1353 Stat1 = 0;
1354 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
1355 Stat2 = 0;
1356 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
1357 Stat1 = Stat1 << 16 | Stat2;
1358 Stat2 = 0;
1359 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
1360 Stat3 = 0;
1361 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
1362 Stat2 = Stat2 << 16 | Stat3;
1363 CMSMPrintString(
1364 pAC->pConfigTable,
1365 MSG_TYPE_RUNTIME_INFO,
1366 "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
1367 (void *)Stat1,
1368 (void *)Stat2);
1369
1370 Stat1 = 0;
1371 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
1372 Stat2 = 0;
1373 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
1374 Stat1 = Stat1 << 16 | Stat2;
1375 Stat2 = 0;
1376 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
1377 Stat3 = 0;
1378 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
1379 Stat2 = Stat2 << 16 | Stat3;
1380 CMSMPrintString(
1381 pAC->pConfigTable,
1382 MSG_TYPE_RUNTIME_INFO,
1383 "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
1384 (void *)Stat1,
1385 (void *)Stat2);
1386 }
1387#endif /* DEBUG */
1388
1389 if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
1390 /*
1391 * Workaround BCom Errata:
1392 * enable and disable loopback mode if "NO HCD" occurs.
1393 */
1394 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
1395 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
1396 (SK_U16)(Ctrl | PHY_CT_LOOP));
1397 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
1398 (SK_U16)(Ctrl & ~PHY_CT_LOOP));
1399 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1400 ("No HCD Link event, Port %d\n", Port));
1401#ifdef xDEBUG
1402 CMSMPrintString(
1403 pAC->pConfigTable,
1404 MSG_TYPE_RUNTIME_INFO,
1405 "No HCD link event, port %d.",
1406 (void *)Port,
1407 (void *)NULL);
1408#endif /* DEBUG */
1409 }
1410
1411 /* Not obsolete: link status bit is latched to 0 and autoclearing! */
1412 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1413
1414 if (pPrt->PHWLinkUp) {
1415 return(SK_HW_PS_NONE);
1416 }
1417
1418#ifdef xDEBUG
1419 {
1420 SK_U32 Stat1, Stat2, Stat3;
1421
1422 Stat1 = 0;
1423 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
1424 CMSMPrintString(
1425 pAC->pConfigTable,
1426 MSG_TYPE_RUNTIME_INFO,
1427 "CheckUp1a - Stat: %x, Mask: %x",
1428 (void *)Isrc,
1429 (void *)Stat1);
1430
1431 Stat1 = 0;
1432 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
1433 Stat2 = 0;
1434 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1435 Stat1 = Stat1 << 16 | PhyStat;
1436 Stat2 = 0;
1437 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
1438 Stat3 = 0;
1439 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
1440 Stat2 = Stat2 << 16 | Stat3;
1441 CMSMPrintString(
1442 pAC->pConfigTable,
1443 MSG_TYPE_RUNTIME_INFO,
1444 "Ctrl/Stat: %x, AN Adv/LP: %x",
1445 (void *)Stat1,
1446 (void *)Stat2);
1447
1448 Stat1 = 0;
1449 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
1450 Stat2 = 0;
1451 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
1452 Stat1 = Stat1 << 16 | Stat2;
1453 Stat2 = 0;
1454 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
1455 Stat3 = 0;
1456 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
1457 Stat2 = Stat2 << 16 | ResAb;
1458 CMSMPrintString(
1459 pAC->pConfigTable,
1460 MSG_TYPE_RUNTIME_INFO,
1461 "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
1462 (void *)Stat1,
1463 (void *)Stat2);
1464
1465 Stat1 = 0;
1466 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
1467 Stat2 = 0;
1468 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
1469 Stat1 = Stat1 << 16 | Stat2;
1470 Stat2 = 0;
1471 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
1472 Stat3 = 0;
1473 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
1474 Stat2 = Stat2 << 16 | Stat3;
1475 CMSMPrintString(
1476 pAC->pConfigTable,
1477 MSG_TYPE_RUNTIME_INFO,
1478 "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
1479 (void *)Stat1,
1480 (void *)Stat2);
1481 }
1482#endif /* DEBUG */
1483
1484 /*
1485 * Here we usually can check whether the link is in sync and
1486 * auto-negotiation is done.
1487 */
1488
1489 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1490
1491 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1492
1493 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1494 ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
1495
1496 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
1497
1498 if ((ResAb & PHY_B_1000S_MSF) != 0) {
1499 /* Error */
1500 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1501 ("Master/Slave Fault port %d\n", Port));
1502
1503 pPrt->PAutoNegFail = SK_TRUE;
1504 pPrt->PMSStatus = SK_MS_STAT_FAULT;
1505
1506 return(SK_HW_PS_RESTART);
1507 }
1508
1509 if ((PhyStat & PHY_ST_LSYNC) == 0) {
1510 return(SK_HW_PS_NONE);
1511 }
1512
1513 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
1514 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
1515
1516 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1517 ("Port %d, ResAb: 0x%04X\n", Port, ResAb));
1518
1519 if (AutoNeg) {
1520 if ((PhyStat & PHY_ST_AN_OVER) != 0) {
1521
1522 SkHWLinkUp(pAC, IoC, Port);
1523
1524 Done = SkMacAutoNegDone(pAC, IoC, Port);
1525
1526 if (Done != SK_AND_OK) {
1527#ifdef DEBUG
1528 /* Get PHY parameters, for debugging only */
1529 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
1530 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
1531 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1532 ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
1533 Port, LpAb, ExtStat));
1534#endif /* DEBUG */
1535 return(SK_HW_PS_RESTART);
1536 }
1537 else {
1538#ifdef xDEBUG
1539 /* Dummy read ISR to prevent extra link downs/ups */
1540 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
1541
1542 if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
1543 CMSMPrintString(
1544 pAC->pConfigTable,
1545 MSG_TYPE_RUNTIME_INFO,
1546 "CheckUp2 - Stat: %x",
1547 (void *)ExtStat,
1548 (void *)NULL);
1549 }
1550#endif /* DEBUG */
1551 return(SK_HW_PS_LINK);
1552 }
1553 }
1554 }
1555 else { /* !AutoNeg */
1556 /* Link is up and we don't need more. */
1557#ifdef DEBUG
1558 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1559 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1560 ("ERROR: Lipa auto detected on port %d\n", Port));
1561 }
1562#endif /* DEBUG */
1563
1564#ifdef xDEBUG
1565 /* Dummy read ISR to prevent extra link downs/ups */
1566 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
1567
1568 if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
1569 CMSMPrintString(
1570 pAC->pConfigTable,
1571 MSG_TYPE_RUNTIME_INFO,
1572 "CheckUp3 - Stat: %x",
1573 (void *)ExtStat,
1574 (void *)NULL);
1575 }
1576#endif /* DEBUG */
1577
1578 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1579 ("Link sync(GP), Port %d\n", Port));
1580 SkHWLinkUp(pAC, IoC, Port);
1581
1582 return(SK_HW_PS_LINK);
1583 }
1584
1585 return(SK_HW_PS_NONE);
1586} /* SkGePortCheckUpBcom */
1587#endif /* GENESIS */
1588
1589
1590#ifdef YUKON
1591/******************************************************************************
1592 *
1593 * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
1594 *
1595 * return:
1596 * 0 o.k. nothing needed
1597 * 1 Restart needed on this port
1598 * 2 Link came up
1599 */
1600static int SkGePortCheckUpGmac(
1601SK_AC *pAC, /* Adapter Context */
1602SK_IOC IoC, /* IO Context */
1603int Port, /* Which port should be checked */
1604SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1605{
1606 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1607 int Done;
1608 SK_U16 PhyIsrc; /* PHY Interrupt source */
1609 SK_U16 PhyStat; /* PPY Status */
1610 SK_U16 PhySpecStat;/* PHY Specific Status */
1611 SK_U16 ResAb; /* Master/Slave resolution */
1612 SK_EVPARA Para;
1613#ifdef DEBUG
1614 SK_U16 Word; /* I/O helper */
1615#endif /* DEBUG */
1616
1617 pPrt = &pAC->GIni.GP[Port];
1618
1619 if (pPrt->PHWLinkUp) {
1620 return(SK_HW_PS_NONE);
1621 }
1622
1623 /* Read PHY Status */
1624 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
1625
1626 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1627 ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
1628
1629 /* Read PHY Interrupt Status */
1630 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
1631
1632 if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
1633 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1634 ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
1635 }
1636
1637 if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
1638 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1639 ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
1640 }
1641
1642 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1643
1644 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
1645
1646 if ((ResAb & PHY_B_1000S_MSF) != 0) {
1647 /* Error */
1648 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1649 ("Master/Slave Fault port %d\n", Port));
1650
1651 pPrt->PAutoNegFail = SK_TRUE;
1652 pPrt->PMSStatus = SK_MS_STAT_FAULT;
1653
1654 return(SK_HW_PS_RESTART);
1655 }
1656
1657 /* Read PHY Specific Status */
1658 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
1659
1660 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1661 ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
1662
1663#ifdef DEBUG
1664 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
1665
1666 if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
1667 (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) {
1668 /* Read PHY Next Page Link Partner */
1669 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
1670
1671 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1672 ("Page Received, NextPage: 0x%04X\n", Word));
1673 }
1674#endif /* DEBUG */
1675
1676 if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
1677 return(SK_HW_PS_NONE);
1678 }
1679
1680 if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
1681 (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
1682 /* Downshift detected */
1683 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
1684
1685 Para.Para64 = Port;
1686 SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
1687
1688 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1689 ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
1690 }
1691
1692 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
1693 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
1694
1695 pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
1696
1697 if (AutoNeg) {
1698 /* Auto-Negotiation Over ? */
1699 if ((PhyStat & PHY_ST_AN_OVER) != 0) {
1700
1701 SkHWLinkUp(pAC, IoC, Port);
1702
1703 Done = SkMacAutoNegDone(pAC, IoC, Port);
1704
1705 if (Done != SK_AND_OK) {
1706 return(SK_HW_PS_RESTART);
1707 }
1708
1709 return(SK_HW_PS_LINK);
1710 }
1711 }
1712 else { /* !AutoNeg */
1713 /* Link is up and we don't need more */
1714#ifdef DEBUG
1715 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1716 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1717 ("ERROR: Lipa auto detected on port %d\n", Port));
1718 }
1719#endif /* DEBUG */
1720
1721 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1722 ("Link sync, Port %d\n", Port));
1723 SkHWLinkUp(pAC, IoC, Port);
1724
1725 return(SK_HW_PS_LINK);
1726 }
1727
1728 return(SK_HW_PS_NONE);
1729} /* SkGePortCheckUpGmac */
1730#endif /* YUKON */
1731
1732
1733#ifdef OTHER_PHY
1734/******************************************************************************
1735 *
1736 * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
1737 *
1738 * return:
1739 * 0 o.k. nothing needed
1740 * 1 Restart needed on this port
1741 * 2 Link came up
1742 */
1743static int SkGePortCheckUpLone(
1744SK_AC *pAC, /* Adapter Context */
1745SK_IOC IoC, /* IO Context */
1746int Port, /* Which port should be checked */
1747SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1748{
1749 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1750 int Done;
1751 SK_U16 Isrc; /* Interrupt source register */
1752 SK_U16 LpAb; /* Link Partner Ability */
1753 SK_U16 ExtStat; /* Extended Status Register */
1754 SK_U16 PhyStat; /* Phy Status Register */
1755 SK_U16 StatSum;
1756 SK_U8 NextMode; /* Next AutoSensing Mode */
1757
1758 pPrt = &pAC->GIni.GP[Port];
1759
1760 if (pPrt->PHWLinkUp) {
1761 return(SK_HW_PS_NONE);
1762 }
1763
1764 StatSum = pPrt->PIsave;
1765 pPrt->PIsave = 0;
1766
1767 /*
1768 * here we usually can check whether the link is in sync and
1769 * auto-negotiation is done.
1770 */
1771 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
1772 StatSum |= PhyStat;
1773
1774 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1775
1776 if ((PhyStat & PHY_ST_LSYNC) == 0) {
1777 /* Save Auto-negotiation Done bit */
1778 pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
1779#ifdef DEBUG
1780 if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
1781 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1782 ("AutoNeg done rescheduled Port %d\n", Port));
1783 }
1784#endif /* DEBUG */
1785 return(SK_HW_PS_NONE);
1786 }
1787
1788 if (AutoNeg) {
1789 if ((StatSum & PHY_ST_AN_OVER) != 0) {
1790 SkHWLinkUp(pAC, IoC, Port);
1791 Done = SkMacAutoNegDone(pAC, IoC, Port);
1792 if (Done != SK_AND_OK) {
1793 /* Get PHY parameters, for debugging only */
1794 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
1795 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
1796 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1797 ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
1798 Port, LpAb, ExtStat));
1799
1800 /* Try next possible mode */
1801 NextMode = SkHWSenseGetNext(pAC, IoC, Port);
1802 SkHWLinkDown(pAC, IoC, Port);
1803 if (Done == SK_AND_DUP_CAP) {
1804 /* GoTo next mode */
1805 SkHWSenseSetNext(pAC, IoC, Port, NextMode);
1806 }
1807
1808 return(SK_HW_PS_RESTART);
1809
1810 }
1811 else {
1812 /*
1813 * Dummy Read interrupt status to prevent
1814 * extra link down/ups
1815 */
1816 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
1817 return(SK_HW_PS_LINK);
1818 }
1819 }
1820
1821 /* AutoNeg not done, but HW link is up. Check for timeouts */
1822 pPrt->PAutoNegTimeOut++;
1823 if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
1824 /* Timeout occured */
1825 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1826 ("AutoNeg timeout Port %d\n", Port));
1827 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1828 pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
1829 /* Set Link manually up */
1830 SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
1831 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1832 ("Set manual full duplex Port %d\n", Port));
1833 }
1834
1835 /* Do the restart */
1836 return(SK_HW_PS_RESTART);
1837 }
1838 }
1839 else {
1840 /* Link is up and we don't need more */
1841#ifdef DEBUG
1842 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1843 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1844 ("ERROR: Lipa auto detected on port %d\n", Port));
1845 }
1846#endif /* DEBUG */
1847
1848 /*
1849 * Dummy Read interrupt status to prevent
1850 * extra link down/ups
1851 */
1852 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
1853
1854 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1855 ("Link sync(GP), Port %d\n", Port));
1856 SkHWLinkUp(pAC, IoC, Port);
1857
1858 return(SK_HW_PS_LINK);
1859 }
1860
1861 return(SK_HW_PS_NONE);
1862} /* SkGePortCheckUpLone */
1863
1864
1865/******************************************************************************
1866 *
1867 * SkGePortCheckUpNat() - Check if the link is up on National PHY
1868 *
1869 * return:
1870 * 0 o.k. nothing needed
1871 * 1 Restart needed on this port
1872 * 2 Link came up
1873 */
1874static int SkGePortCheckUpNat(
1875SK_AC *pAC, /* Adapter Context */
1876SK_IOC IoC, /* IO Context */
1877int Port, /* Which port should be checked */
1878SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1879{
1880 /* todo: National */
1881 return(SK_HW_PS_NONE);
1882} /* SkGePortCheckUpNat */
1883#endif /* OTHER_PHY */
1884
1885
1886/******************************************************************************
1887 *
1888 * SkGeSirqEvent() - Event Service Routine
1889 *
1890 * Description:
1891 *
1892 * Notes:
1893 */
1894int SkGeSirqEvent(
1895SK_AC *pAC, /* Adapter Context */
1896SK_IOC IoC, /* Io Context */
1897SK_U32 Event, /* Module specific Event */
1898SK_EVPARA Para) /* Event specific Parameter */
1899{
1900 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1901 SK_U32 Port;
1902 SK_U32 Val32;
1903 int PortStat;
1904 SK_U8 Val8;
1905#ifdef GENESIS
1906 SK_U64 Octets;
1907#endif /* GENESIS */
1908
1909 Port = Para.Para32[0];
1910 pPrt = &pAC->GIni.GP[Port];
1911
1912 switch (Event) {
1913 case SK_HWEV_WATIM:
1914 if (pPrt->PState == SK_PRT_RESET) {
1915
1916 PortStat = SK_HW_PS_NONE;
1917 }
1918 else {
1919 /* Check whether port came up */
1920 PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
1921 }
1922
1923 switch (PortStat) {
1924 case SK_HW_PS_RESTART:
1925 if (pPrt->PHWLinkUp) {
1926 /* Set Link to down */
1927 SkHWLinkDown(pAC, IoC, (int)Port);
1928
1929 /*
1930 * Signal directly to RLMT to ensure correct
1931 * sequence of SWITCH and RESET event.
1932 */
1933 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1934 }
1935
1936 /* Restart needed */
1937 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
1938 break;
1939
1940 case SK_HW_PS_LINK:
1941 /* Signal to RLMT */
1942 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
1943 break;
1944 }
1945
1946 /* Start again the check Timer */
1947 if (pPrt->PHWLinkUp) {
1948 Val32 = SK_WA_ACT_TIME;
1949 }
1950 else {
1951 Val32 = SK_WA_INA_TIME;
1952 }
1953
1954 /* Todo: still needed for non-XMAC PHYs??? */
1955 /* Start workaround Errata #2 timer */
1956 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
1957 SKGE_HWAC, SK_HWEV_WATIM, Para);
1958 break;
1959
1960 case SK_HWEV_PORT_START:
1961 if (pPrt->PHWLinkUp) {
1962 /*
1963 * Signal directly to RLMT to ensure correct
1964 * sequence of SWITCH and RESET event.
1965 */
1966 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1967 }
1968
1969 SkHWLinkDown(pAC, IoC, (int)Port);
1970
1971 /* Schedule Port RESET */
1972 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
1973
1974 /* Start workaround Errata #2 timer */
1975 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
1976 SKGE_HWAC, SK_HWEV_WATIM, Para);
1977 break;
1978
1979 case SK_HWEV_PORT_STOP:
1980 if (pPrt->PHWLinkUp) {
1981 /*
1982 * Signal directly to RLMT to ensure correct
1983 * sequence of SWITCH and RESET event.
1984 */
1985 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1986 }
1987
1988 /* Stop Workaround Timer */
1989 SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
1990
1991 SkHWLinkDown(pAC, IoC, (int)Port);
1992 break;
1993
1994 case SK_HWEV_UPDATE_STAT:
1995 /* We do NOT need to update any statistics */
1996 break;
1997
1998 case SK_HWEV_CLEAR_STAT:
1999 /* We do NOT need to clear any statistics */
2000 for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
2001 pPrt->PPrevRx = 0;
2002 pPrt->PPrevFcs = 0;
2003 pPrt->PPrevShorts = 0;
2004 }
2005 break;
2006
2007 case SK_HWEV_SET_LMODE:
2008 Val8 = (SK_U8)Para.Para32[1];
2009 if (pPrt->PLinkModeConf != Val8) {
2010 /* Set New link mode */
2011 pPrt->PLinkModeConf = Val8;
2012
2013 /* Restart Port */
2014 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2015 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2016 }
2017 break;
2018
2019 case SK_HWEV_SET_FLOWMODE:
2020 Val8 = (SK_U8)Para.Para32[1];
2021 if (pPrt->PFlowCtrlMode != Val8) {
2022 /* Set New Flow Control mode */
2023 pPrt->PFlowCtrlMode = Val8;
2024
2025 /* Restart Port */
2026 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2027 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2028 }
2029 break;
2030
2031 case SK_HWEV_SET_ROLE:
2032 /* not possible for fiber */
2033 if (!pAC->GIni.GICopperType) {
2034 break;
2035 }
2036 Val8 = (SK_U8)Para.Para32[1];
2037 if (pPrt->PMSMode != Val8) {
2038 /* Set New Role (Master/Slave) mode */
2039 pPrt->PMSMode = Val8;
2040
2041 /* Restart Port */
2042 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2043 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2044 }
2045 break;
2046
2047 case SK_HWEV_SET_SPEED:
2048 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
2049 break;
2050 }
2051 Val8 = (SK_U8)Para.Para32[1];
2052 if (pPrt->PLinkSpeed != Val8) {
2053 /* Set New Speed parameter */
2054 pPrt->PLinkSpeed = Val8;
2055
2056 /* Restart Port */
2057 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2058 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2059 }
2060 break;
2061
2062#ifdef GENESIS
2063 case SK_HWEV_HALFDUP_CHK:
2064 if (pAC->GIni.GIGenesis) {
2065 /*
2066 * half duplex hangup workaround.
2067 * See packet arbiter timeout interrupt for description
2068 */
2069 pPrt->HalfDupTimerActive = SK_FALSE;
2070 if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
2071 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
2072 /* Snap statistic counters */
2073 (void)SkXmUpdateStats(pAC, IoC, Port);
2074
2075 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
2076
2077 Octets = (SK_U64)Val32 << 32;
2078
2079 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
2080
2081 Octets += Val32;
2082
2083 if (pPrt->LastOctets == Octets) {
2084 /* Tx hanging, a FIFO flush restarts it */
2085 SkMacFlushTxFifo(pAC, IoC, Port);
2086 }
2087 }
2088 }
2089 break;
2090#endif /* GENESIS */
2091
2092 default:
2093 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
2094 break;
2095 }
2096
2097 return(0);
2098} /* SkGeSirqEvent */
2099
2100
2101#ifdef GENESIS
2102/******************************************************************************
2103 *
2104 * SkPhyIsrBcom() - PHY interrupt service routine
2105 *
2106 * Description: handles all interrupts from BCom PHY
2107 *
2108 * Returns: N/A
2109 */
2110static void SkPhyIsrBcom(
2111SK_AC *pAC, /* Adapter Context */
2112SK_IOC IoC, /* Io Context */
2113int Port, /* Port Num = PHY Num */
2114SK_U16 IStatus) /* Interrupt Status */
2115{
2116 SK_GEPORT *pPrt; /* GIni Port struct pointer */
2117 SK_EVPARA Para;
2118
2119 pPrt = &pAC->GIni.GP[Port];
2120
2121 if ((IStatus & PHY_B_IS_PSE) != 0) {
2122 /* Incorrectable pair swap error */
2123 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
2124 SKERR_SIRQ_E022MSG);
2125 }
2126
2127 if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
2128
2129 SkHWLinkDown(pAC, IoC, Port);
2130
2131 Para.Para32[0] = (SK_U32)Port;
2132 /* Signal to RLMT */
2133 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2134
2135 /* Start workaround Errata #2 timer */
2136 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
2137 SKGE_HWAC, SK_HWEV_WATIM, Para);
2138 }
2139
2140} /* SkPhyIsrBcom */
2141#endif /* GENESIS */
2142
2143
2144#ifdef YUKON
2145/******************************************************************************
2146 *
2147 * SkPhyIsrGmac() - PHY interrupt service routine
2148 *
2149 * Description: handles all interrupts from Marvell PHY
2150 *
2151 * Returns: N/A
2152 */
2153static void SkPhyIsrGmac(
2154SK_AC *pAC, /* Adapter Context */
2155SK_IOC IoC, /* Io Context */
2156int Port, /* Port Num = PHY Num */
2157SK_U16 IStatus) /* Interrupt Status */
2158{
2159 SK_GEPORT *pPrt; /* GIni Port struct pointer */
2160 SK_EVPARA Para;
2161 SK_U16 Word;
2162
2163 pPrt = &pAC->GIni.GP[Port];
2164
2165 if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
2166
2167 SkHWLinkDown(pAC, IoC, Port);
2168
2169 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
2170
2171 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2172 ("AutoNeg.Adv: 0x%04X\n", Word));
2173
2174 /* Set Auto-negotiation advertisement */
2175 if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
2176 /* restore Asymmetric Pause bit */
2177 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
2178 (SK_U16)(Word | PHY_M_AN_ASP));
2179 }
2180
2181 Para.Para32[0] = (SK_U32)Port;
2182 /* Signal to RLMT */
2183 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2184 }
2185
2186 if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
2187 /* Auto-Negotiation Error */
2188 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
2189 }
2190
2191 if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
2192 /* FIFO Overflow/Underrun Error */
2193 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
2194 }
2195
2196} /* SkPhyIsrGmac */
2197#endif /* YUKON */
2198
2199
2200#ifdef OTHER_PHY
2201/******************************************************************************
2202 *
2203 * SkPhyIsrLone() - PHY interrupt service routine
2204 *
2205 * Description: handles all interrupts from LONE PHY
2206 *
2207 * Returns: N/A
2208 */
2209static void SkPhyIsrLone(
2210SK_AC *pAC, /* Adapter Context */
2211SK_IOC IoC, /* Io Context */
2212int Port, /* Port Num = PHY Num */
2213SK_U16 IStatus) /* Interrupt Status */
2214{
2215 SK_EVPARA Para;
2216
2217 if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
2218
2219 SkHWLinkDown(pAC, IoC, Port);
2220
2221 Para.Para32[0] = (SK_U32)Port;
2222 /* Signal to RLMT */
2223 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2224 }
2225
2226} /* SkPhyIsrLone */
2227#endif /* OTHER_PHY */
2228
2229/* End of File */
diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
deleted file mode 100644
index 79bf57cb5326..000000000000
--- a/drivers/net/sk98lin/ski2c.c
+++ /dev/null
@@ -1,1296 +0,0 @@
1/******************************************************************************
2 *
3 * Name: ski2c.c
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.59 $
6 * Date: $Date: 2003/10/20 09:07:25 $
7 * Purpose: Functions to access Voltage and Temperature Sensor
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * I2C Protocol
27 */
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/lm80.h"
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#ifdef __C2MAN__
38/*
39 I2C protocol implementation.
40
41 General Description:
42
43 The I2C protocol is used for the temperature sensors and for
44 the serial EEPROM which hold the configuration.
45
46 This file covers functions that allow to read write and do
47 some bulk requests a specified I2C address.
48
49 The Genesis has 2 I2C buses. One for the EEPROM which holds
50 the VPD Data and one for temperature and voltage sensor.
51 The following picture shows the I2C buses, I2C devices and
52 their control registers.
53
54 Note: The VPD functions are in skvpd.c
55.
56. PCI Config I2C Bus for VPD Data:
57.
58. +------------+
59. | VPD EEPROM |
60. +------------+
61. |
62. | <-- I2C
63. |
64. +-----------+-----------+
65. | |
66. +-----------------+ +-----------------+
67. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
68. +-----------------+ +-----------------+
69.
70.
71. I2C Bus for LM80 sensor:
72.
73. +-----------------+
74. | Temperature and |
75. | Voltage Sensor |
76. | LM80 |
77. +-----------------+
78. |
79. |
80. I2C --> |
81. |
82. +----+
83. +-------------->| OR |<--+
84. | +----+ |
85. +------+------+ |
86. | | |
87. +--------+ +--------+ +----------+
88. | B2_I2C | | B2_I2C | | B2_I2C |
89. | _CTRL | | _DATA | | _SW |
90. +--------+ +--------+ +----------+
91.
92 The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
93 and B2_I2C_DATA registers.
94 For driver software it is recommended to use the I2C control and
95 data register, because I2C bus timing is done by the ASIC and
96 an interrupt may be received when the I2C request is completed.
97
98 Clock Rate Timing: MIN MAX generated by
99 VPD EEPROM: 50 kHz 100 kHz HW
100 LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
101 LM80 over B2_I2C_SW register 0 400 kHz SW
102
103 Note: The clock generated by the hardware is dependend on the
104 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
105 clock is 50 kHz.
106 */
107intro()
108{}
109#endif
110
111#ifdef SK_DIAG
112/*
113 * I2C Fast Mode timing values used by the LM80.
114 * If new devices are added to the I2C bus the timing values have to be checked.
115 */
116#ifndef I2C_SLOW_TIMING
117#define T_CLK_LOW 1300L /* clock low time in ns */
118#define T_CLK_HIGH 600L /* clock high time in ns */
119#define T_DATA_IN_SETUP 100L /* data in Set-up Time */
120#define T_START_HOLD 600L /* start condition hold time */
121#define T_START_SETUP 600L /* start condition Set-up time */
122#define T_STOP_SETUP 600L /* stop condition Set-up time */
123#define T_BUS_IDLE 1300L /* time the bus must free after Tx */
124#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
125#else /* I2C_SLOW_TIMING */
126/* I2C Standard Mode Timing */
127#define T_CLK_LOW 4700L /* clock low time in ns */
128#define T_CLK_HIGH 4000L /* clock high time in ns */
129#define T_DATA_IN_SETUP 250L /* data in Set-up Time */
130#define T_START_HOLD 4000L /* start condition hold time */
131#define T_START_SETUP 4700L /* start condition Set-up time */
132#define T_STOP_SETUP 4000L /* stop condition Set-up time */
133#define T_BUS_IDLE 4700L /* time the bus must free after Tx */
134#endif /* !I2C_SLOW_TIMING */
135
136#define NS2BCLK(x) (((x)*125)/10000)
137
138/*
139 * I2C Wire Operations
140 *
141 * About I2C_CLK_LOW():
142 *
143 * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
144 * clock to low, to prevent the ASIC and the I2C data client from driving the
145 * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
146 * send an 'ACK'). See also Concentrator Bugreport No. 10192.
147 */
148#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
149#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
150#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
151#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
152#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
153#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
154#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
155
156#define NS2CLKT(x) ((x*125L)/10000)
157
158/*--------------- I2C Interface Register Functions --------------- */
159
160/*
161 * sending one bit
162 */
163void SkI2cSndBit(
164SK_IOC IoC, /* I/O Context */
165SK_U8 Bit) /* Bit to send */
166{
167 I2C_DATA_OUT(IoC);
168 if (Bit) {
169 I2C_DATA_HIGH(IoC);
170 }
171 else {
172 I2C_DATA_LOW(IoC);
173 }
174 SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
175 I2C_CLK_HIGH(IoC);
176 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
177 I2C_CLK_LOW(IoC);
178} /* SkI2cSndBit*/
179
180
181/*
182 * Signal a start to the I2C Bus.
183 *
184 * A start is signaled when data goes to low in a high clock cycle.
185 *
186 * Ends with Clock Low.
187 *
188 * Status: not tested
189 */
190void SkI2cStart(
191SK_IOC IoC) /* I/O Context */
192{
193 /* Init data and Clock to output lines */
194 /* Set Data high */
195 I2C_DATA_OUT(IoC);
196 I2C_DATA_HIGH(IoC);
197 /* Set Clock high */
198 I2C_CLK_HIGH(IoC);
199
200 SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
201
202 /* Set Data Low */
203 I2C_DATA_LOW(IoC);
204
205 SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
206
207 /* Clock low without Data to Input */
208 I2C_START_COND(IoC);
209
210 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
211} /* SkI2cStart */
212
213
214void SkI2cStop(
215SK_IOC IoC) /* I/O Context */
216{
217 /* Init data and Clock to output lines */
218 /* Set Data low */
219 I2C_DATA_OUT(IoC);
220 I2C_DATA_LOW(IoC);
221
222 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
223
224 /* Set Clock high */
225 I2C_CLK_HIGH(IoC);
226
227 SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
228
229 /*
230 * Set Data High: Do it by setting the Data Line to Input.
231 * Because of a pull up resistor the Data Line
232 * floods to high.
233 */
234 I2C_DATA_IN(IoC);
235
236 /*
237 * When I2C activity is stopped
238 * o DATA should be set to input and
239 * o CLOCK should be set to high!
240 */
241 SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
242} /* SkI2cStop */
243
244
245/*
246 * Receive just one bit via the I2C bus.
247 *
248 * Note: Clock must be set to LOW before calling this function.
249 *
250 * Returns The received bit.
251 */
252int SkI2cRcvBit(
253SK_IOC IoC) /* I/O Context */
254{
255 int Bit;
256 SK_U8 I2cSwCtrl;
257
258 /* Init data as input line */
259 I2C_DATA_IN(IoC);
260
261 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
262
263 I2C_CLK_HIGH(IoC);
264
265 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
266
267 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
268
269 Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
270
271 I2C_CLK_LOW(IoC);
272 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
273
274 return(Bit);
275} /* SkI2cRcvBit */
276
277
278/*
279 * Receive an ACK.
280 *
281 * returns 0 If acknowledged
282 * 1 in case of an error
283 */
284int SkI2cRcvAck(
285SK_IOC IoC) /* I/O Context */
286{
287 /*
288 * Received bit must be zero.
289 */
290 return(SkI2cRcvBit(IoC) != 0);
291} /* SkI2cRcvAck */
292
293
294/*
295 * Send an NACK.
296 */
297void SkI2cSndNAck(
298SK_IOC IoC) /* I/O Context */
299{
300 /*
301 * Received bit must be zero.
302 */
303 SkI2cSndBit(IoC, 1);
304} /* SkI2cSndNAck */
305
306
307/*
308 * Send an ACK.
309 */
310void SkI2cSndAck(
311SK_IOC IoC) /* I/O Context */
312{
313 /*
314 * Received bit must be zero.
315 */
316 SkI2cSndBit(IoC, 0);
317} /* SkI2cSndAck */
318
319
320/*
321 * Send one byte to the I2C device and wait for ACK.
322 *
323 * Return acknowleged status.
324 */
325int SkI2cSndByte(
326SK_IOC IoC, /* I/O Context */
327int Byte) /* byte to send */
328{
329 int i;
330
331 for (i = 0; i < 8; i++) {
332 if (Byte & (1<<(7-i))) {
333 SkI2cSndBit(IoC, 1);
334 }
335 else {
336 SkI2cSndBit(IoC, 0);
337 }
338 }
339
340 return(SkI2cRcvAck(IoC));
341} /* SkI2cSndByte */
342
343
344/*
345 * Receive one byte and ack it.
346 *
347 * Return byte.
348 */
349int SkI2cRcvByte(
350SK_IOC IoC, /* I/O Context */
351int Last) /* Last Byte Flag */
352{
353 int i;
354 int Byte = 0;
355
356 for (i = 0; i < 8; i++) {
357 Byte <<= 1;
358 Byte |= SkI2cRcvBit(IoC);
359 }
360
361 if (Last) {
362 SkI2cSndNAck(IoC);
363 }
364 else {
365 SkI2cSndAck(IoC);
366 }
367
368 return(Byte);
369} /* SkI2cRcvByte */
370
371
372/*
373 * Start dialog and send device address
374 *
375 * Return 0 if acknowleged, 1 in case of an error
376 */
377int SkI2cSndDev(
378SK_IOC IoC, /* I/O Context */
379int Addr, /* Device Address */
380int Rw) /* Read / Write Flag */
381{
382 SkI2cStart(IoC);
383 Rw = ~Rw;
384 Rw &= I2C_WRITE;
385 return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
386} /* SkI2cSndDev */
387
388#endif /* SK_DIAG */
389
390/*----------------- I2C CTRL Register Functions ----------*/
391
392/*
393 * waits for a completion of an I2C transfer
394 *
395 * returns 0: success, transfer completes
396 * 1: error, transfer does not complete, I2C transfer
397 * killed, wait loop terminated.
398 */
399static int SkI2cWait(
400SK_AC *pAC, /* Adapter Context */
401SK_IOC IoC, /* I/O Context */
402int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
403{
404 SK_U64 StartTime;
405 SK_U64 CurrentTime;
406 SK_U32 I2cCtrl;
407
408 StartTime = SkOsGetTime(pAC);
409
410 do {
411 CurrentTime = SkOsGetTime(pAC);
412
413 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
414
415 SK_I2C_STOP(IoC);
416#ifndef SK_DIAG
417 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
418#endif /* !SK_DIAG */
419 return(1);
420 }
421
422 SK_I2C_GET_CTL(IoC, &I2cCtrl);
423
424#ifdef xYUKON_DBG
425 printf("StartTime=%lu, CurrentTime=%lu\n",
426 StartTime, CurrentTime);
427 if (kbhit()) {
428 return(1);
429 }
430#endif /* YUKON_DBG */
431
432 } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
433
434 return(0);
435} /* SkI2cWait */
436
437
438/*
439 * waits for a completion of an I2C transfer
440 *
441 * Returns
442 * Nothing
443 */
444void SkI2cWaitIrq(
445SK_AC *pAC, /* Adapter Context */
446SK_IOC IoC) /* I/O Context */
447{
448 SK_SENSOR *pSen;
449 SK_U64 StartTime;
450 SK_U32 IrqSrc;
451
452 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
453
454 if (pSen->SenState == SK_SEN_IDLE) {
455 return;
456 }
457
458 StartTime = SkOsGetTime(pAC);
459
460 do {
461 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
462
463 SK_I2C_STOP(IoC);
464#ifndef SK_DIAG
465 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
466#endif /* !SK_DIAG */
467 return;
468 }
469
470 SK_IN32(IoC, B0_ISRC, &IrqSrc);
471
472 } while ((IrqSrc & IS_I2C_READY) == 0);
473
474 pSen->SenState = SK_SEN_IDLE;
475 return;
476} /* SkI2cWaitIrq */
477
478/*
479 * writes a single byte or 4 bytes into the I2C device
480 *
481 * returns 0: success
482 * 1: error
483 */
484static int SkI2cWrite(
485SK_AC *pAC, /* Adapter Context */
486SK_IOC IoC, /* I/O Context */
487SK_U32 I2cData, /* I2C Data to write */
488int I2cDev, /* I2C Device Address */
489int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
490int I2cReg, /* I2C Device Register Address */
491int I2cBurst) /* I2C Burst Flag */
492{
493 SK_OUT32(IoC, B2_I2C_DATA, I2cData);
494
495 SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
496
497 return(SkI2cWait(pAC, IoC, I2C_WRITE));
498} /* SkI2cWrite*/
499
500
501#ifdef SK_DIAG
502/*
503 * reads a single byte or 4 bytes from the I2C device
504 *
505 * returns the word read
506 */
507SK_U32 SkI2cRead(
508SK_AC *pAC, /* Adapter Context */
509SK_IOC IoC, /* I/O Context */
510int I2cDev, /* I2C Device Address */
511int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
512int I2cReg, /* I2C Device Register Address */
513int I2cBurst) /* I2C Burst Flag */
514{
515 SK_U32 Data;
516
517 SK_OUT32(IoC, B2_I2C_DATA, 0);
518 SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
519
520 if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
521 w_print("%s\n", SKERR_I2C_E002MSG);
522 }
523
524 SK_IN32(IoC, B2_I2C_DATA, &Data);
525
526 return(Data);
527} /* SkI2cRead */
528#endif /* SK_DIAG */
529
530
531/*
532 * read a sensor's value
533 *
534 * This function reads a sensor's value from the I2C sensor chip. The sensor
535 * is defined by its index into the sensors database in the struct pAC points
536 * to.
537 * Returns
538 * 1 if the read is completed
539 * 0 if the read must be continued (I2C Bus still allocated)
540 */
541static int SkI2cReadSensor(
542SK_AC *pAC, /* Adapter Context */
543SK_IOC IoC, /* I/O Context */
544SK_SENSOR *pSen) /* Sensor to be read */
545{
546 if (pSen->SenRead != NULL) {
547 return((*pSen->SenRead)(pAC, IoC, pSen));
548 }
549 else {
550 return(0); /* no success */
551 }
552} /* SkI2cReadSensor */
553
554/*
555 * Do the Init state 0 initialization
556 */
557static int SkI2cInit0(
558SK_AC *pAC) /* Adapter Context */
559{
560 int i;
561
562 /* Begin with first sensor */
563 pAC->I2c.CurrSens = 0;
564
565 /* Begin with timeout control for state machine */
566 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
567
568 /* Set sensor number to zero */
569 pAC->I2c.MaxSens = 0;
570
571#ifndef SK_DIAG
572 /* Initialize Number of Dummy Reads */
573 pAC->I2c.DummyReads = SK_MAX_SENSORS;
574#endif
575
576 for (i = 0; i < SK_MAX_SENSORS; i++) {
577 pAC->I2c.SenTable[i].SenDesc = "unknown";
578 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
579 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
580 pAC->I2c.SenTable[i].SenThreErrLow = 0;
581 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
582 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
583 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
584 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
585 pAC->I2c.SenTable[i].SenValue = 0;
586 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
587 pAC->I2c.SenTable[i].SenErrCts = 0;
588 pAC->I2c.SenTable[i].SenBegErrTS = 0;
589 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
590 pAC->I2c.SenTable[i].SenRead = NULL;
591 pAC->I2c.SenTable[i].SenDev = 0;
592 }
593
594 /* Now we are "INIT data"ed */
595 pAC->I2c.InitLevel = SK_INIT_DATA;
596 return(0);
597} /* SkI2cInit0*/
598
599
600/*
601 * Do the init state 1 initialization
602 *
603 * initialize the following register of the LM80:
604 * Configuration register:
605 * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
606 *
607 * Interrupt Mask Register 1:
608 * - all interrupts are Disabled (0xff)
609 *
610 * Interrupt Mask Register 2:
611 * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
612 *
613 * Fan Divisor/RST_OUT register:
614 * - Divisors set to 1 (bits 00), all others 0s.
615 *
616 * OS# Configuration/Temperature resolution Register:
617 * - all 0s
618 *
619 */
620static int SkI2cInit1(
621SK_AC *pAC, /* Adapter Context */
622SK_IOC IoC) /* I/O Context */
623{
624 int i;
625 SK_U8 I2cSwCtrl;
626 SK_GEPORT *pPrt; /* GIni Port struct pointer */
627
628 if (pAC->I2c.InitLevel != SK_INIT_DATA) {
629 /* ReInit not needed in I2C module */
630 return(0);
631 }
632
633 /* Set the Direction of I2C-Data Pin to IN */
634 SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
635 /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
636 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
637
638 if ((I2cSwCtrl & I2C_DATA) == 0) {
639 /* this is a 32-Bit board */
640 pAC->GIni.GIYukon32Bit = SK_TRUE;
641 return(0);
642 }
643
644 /* Check for 64 Bit Yukon without sensors */
645 if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
646 return(0);
647 }
648
649 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
650
651 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
652
653 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
654
655 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
656
657 (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
658 LM80_CFG, 0);
659
660 /*
661 * MaxSens has to be updated here, because PhyType is not
662 * set when performing Init Level 0
663 */
664 pAC->I2c.MaxSens = 5;
665
666 pPrt = &pAC->GIni.GP[0];
667
668 if (pAC->GIni.GIGenesis) {
669 if (pPrt->PhyType == SK_PHY_BCOM) {
670 if (pAC->GIni.GIMacsFound == 1) {
671 pAC->I2c.MaxSens += 1;
672 }
673 else {
674 pAC->I2c.MaxSens += 3;
675 }
676 }
677 }
678 else {
679 pAC->I2c.MaxSens += 3;
680 }
681
682 for (i = 0; i < pAC->I2c.MaxSens; i++) {
683 switch (i) {
684 case 0:
685 pAC->I2c.SenTable[i].SenDesc = "Temperature";
686 pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
687 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
688 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
689 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
690 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
691 pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
692 break;
693 case 1:
694 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
695 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
696 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
697 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
698 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
699 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
700 pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
701 break;
702 case 2:
703 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
704 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
705 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
706 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
707 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
708 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
709 pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
710 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
711 break;
712 case 3:
713 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
714 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
715 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
716 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
717 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
718 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
719 pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
720 break;
721 case 4:
722 if (pAC->GIni.GIGenesis) {
723 if (pPrt->PhyType == SK_PHY_BCOM) {
724 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
725 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
726 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
727 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
728 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
729 }
730 else {
731 pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
732 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
733 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
734 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
735 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
736 }
737 }
738 else {
739 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
740 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
741 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
742 if (pAC->GIni.GIVauxAvail) {
743 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
744 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
745 }
746 else {
747 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
748 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
749 }
750 }
751 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
752 pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
753 break;
754 case 5:
755 if (pAC->GIni.GIGenesis) {
756 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
757 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
758 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
759 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
760 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
761 }
762 else {
763 pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
764 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
765 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
766 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
767 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
768 }
769 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
770 pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
771 break;
772 case 6:
773 if (pAC->GIni.GIGenesis) {
774 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
775 }
776 else {
777 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
778 }
779 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
780 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
781 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
782 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
783 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
784 pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
785 break;
786 case 7:
787 if (pAC->GIni.GIGenesis) {
788 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
789 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
790 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
791 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
792 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
793 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
794 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
795 }
796 else {
797 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
798 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
799 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
800 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
801 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
802 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
803 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
804 }
805 break;
806 default:
807 SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
808 SKERR_I2C_E001, SKERR_I2C_E001MSG);
809 break;
810 }
811
812 pAC->I2c.SenTable[i].SenValue = 0;
813 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
814 pAC->I2c.SenTable[i].SenErrCts = 0;
815 pAC->I2c.SenTable[i].SenBegErrTS = 0;
816 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
817 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
818 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
819 }
820
821#ifndef SK_DIAG
822 pAC->I2c.DummyReads = pAC->I2c.MaxSens;
823#endif /* !SK_DIAG */
824
825 /* Clear I2C IRQ */
826 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
827
828 /* Now we are I/O initialized */
829 pAC->I2c.InitLevel = SK_INIT_IO;
830 return(0);
831} /* SkI2cInit1 */
832
833
834/*
835 * Init level 2: Start first sensor read.
836 */
837static int SkI2cInit2(
838SK_AC *pAC, /* Adapter Context */
839SK_IOC IoC) /* I/O Context */
840{
841 int ReadComplete;
842 SK_SENSOR *pSen;
843
844 if (pAC->I2c.InitLevel != SK_INIT_IO) {
845 /* ReInit not needed in I2C module */
846 /* Init0 and Init2 not permitted */
847 return(0);
848 }
849
850 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
851 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
852
853 if (ReadComplete) {
854 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
855 }
856
857 /* Now we are correctly initialized */
858 pAC->I2c.InitLevel = SK_INIT_RUN;
859
860 return(0);
861} /* SkI2cInit2*/
862
863
864/*
865 * Initialize I2C devices
866 *
867 * Get the first voltage value and discard it.
868 * Go into temperature read mode. A default pointer is not set.
869 *
870 * The things to be done depend on the init level in the parameter list:
871 * Level 0:
872 * Initialize only the data structures. Do NOT access hardware.
873 * Level 1:
874 * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
875 * Level 2:
876 * Everything is possible. Interrupts may be used from now on.
877 *
878 * return:
879 * 0 = success
880 * other = error.
881 */
882int SkI2cInit(
883SK_AC *pAC, /* Adapter Context */
884SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
885int Level) /* Init Level */
886{
887
888 switch (Level) {
889 case SK_INIT_DATA:
890 return(SkI2cInit0(pAC));
891 case SK_INIT_IO:
892 return(SkI2cInit1(pAC, IoC));
893 case SK_INIT_RUN:
894 return(SkI2cInit2(pAC, IoC));
895 default:
896 break;
897 }
898
899 return(0);
900} /* SkI2cInit */
901
902
903#ifndef SK_DIAG
904
905/*
906 * Interrupt service function for the I2C Interface
907 *
908 * Clears the Interrupt source
909 *
910 * Reads the register and check it for sending a trap.
911 *
912 * Starts the timer if necessary.
913 */
914void SkI2cIsr(
915SK_AC *pAC, /* Adapter Context */
916SK_IOC IoC) /* I/O Context */
917{
918 SK_EVPARA Para;
919
920 /* Clear I2C IRQ */
921 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
922
923 Para.Para64 = 0;
924 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
925} /* SkI2cIsr */
926
927
928/*
929 * Check this sensors Value against the threshold and send events.
930 */
931static void SkI2cCheckSensor(
932SK_AC *pAC, /* Adapter Context */
933SK_SENSOR *pSen)
934{
935 SK_EVPARA ParaLocal;
936 SK_BOOL TooHigh; /* Is sensor too high? */
937 SK_BOOL TooLow; /* Is sensor too low? */
938 SK_U64 CurrTime; /* Current Time */
939 SK_BOOL DoTrapSend; /* We need to send a trap */
940 SK_BOOL DoErrLog; /* We need to log the error */
941 SK_BOOL IsError; /* We need to log the error */
942
943 /* Check Dummy Reads first */
944 if (pAC->I2c.DummyReads > 0) {
945 pAC->I2c.DummyReads--;
946 return;
947 }
948
949 /* Get the current time */
950 CurrTime = SkOsGetTime(pAC);
951
952 /* Set para to the most useful setting: The current sensor. */
953 ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
954
955 /* Check the Value against the thresholds. First: Error Thresholds */
956 TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
957 TooLow = (pSen->SenValue < pSen->SenThreErrLow);
958
959 IsError = SK_FALSE;
960 if (TooHigh || TooLow) {
961 /* Error condition is satisfied */
962 DoTrapSend = SK_TRUE;
963 DoErrLog = SK_TRUE;
964
965 /* Now error condition is satisfied */
966 IsError = SK_TRUE;
967
968 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
969 /* This state is the former one */
970
971 /* So check first whether we have to send a trap */
972 if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
973 CurrTime) {
974 /*
975 * Do NOT send the Trap. The hold back time
976 * has to run out first.
977 */
978 DoTrapSend = SK_FALSE;
979 }
980
981 /* Check now whether we have to log an Error */
982 if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
983 CurrTime) {
984 /*
985 * Do NOT log the error. The hold back time
986 * has to run out first.
987 */
988 DoErrLog = SK_FALSE;
989 }
990 }
991 else {
992 /* We came from a different state -> Set Begin Time Stamp */
993 pSen->SenBegErrTS = CurrTime;
994 pSen->SenErrFlag = SK_SEN_ERR_ERR;
995 }
996
997 if (DoTrapSend) {
998 /* Set current Time */
999 pSen->SenLastErrTrapTS = CurrTime;
1000 pSen->SenErrCts++;
1001
1002 /* Queue PNMI Event */
1003 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1004 SK_PNMI_EVT_SEN_ERR_UPP :
1005 SK_PNMI_EVT_SEN_ERR_LOW),
1006 ParaLocal);
1007 }
1008
1009 if (DoErrLog) {
1010 /* Set current Time */
1011 pSen->SenLastErrLogTS = CurrTime;
1012
1013 if (pSen->SenType == SK_SEN_TEMP) {
1014 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
1015 }
1016 else if (pSen->SenType == SK_SEN_VOLT) {
1017 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
1018 }
1019 else {
1020 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
1021 }
1022 }
1023 }
1024
1025 /* Check the Value against the thresholds */
1026 /* 2nd: Warning thresholds */
1027 TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1028 TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1029
1030 if (!IsError && (TooHigh || TooLow)) {
1031 /* Error condition is satisfied */
1032 DoTrapSend = SK_TRUE;
1033 DoErrLog = SK_TRUE;
1034
1035 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1036 /* This state is the former one */
1037
1038 /* So check first whether we have to send a trap */
1039 if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
1040 /*
1041 * Do NOT send the Trap. The hold back time
1042 * has to run out first.
1043 */
1044 DoTrapSend = SK_FALSE;
1045 }
1046
1047 /* Check now whether we have to log an Error */
1048 if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
1049 /*
1050 * Do NOT log the error. The hold back time
1051 * has to run out first.
1052 */
1053 DoErrLog = SK_FALSE;
1054 }
1055 }
1056 else {
1057 /* We came from a different state -> Set Begin Time Stamp */
1058 pSen->SenBegWarnTS = CurrTime;
1059 pSen->SenErrFlag = SK_SEN_ERR_WARN;
1060 }
1061
1062 if (DoTrapSend) {
1063 /* Set current Time */
1064 pSen->SenLastWarnTrapTS = CurrTime;
1065 pSen->SenWarnCts++;
1066
1067 /* Queue PNMI Event */
1068 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1069 SK_PNMI_EVT_SEN_WAR_UPP :
1070 SK_PNMI_EVT_SEN_WAR_LOW),
1071 ParaLocal);
1072 }
1073
1074 if (DoErrLog) {
1075 /* Set current Time */
1076 pSen->SenLastWarnLogTS = CurrTime;
1077
1078 if (pSen->SenType == SK_SEN_TEMP) {
1079 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
1080 }
1081 else if (pSen->SenType == SK_SEN_VOLT) {
1082 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
1083 }
1084 else {
1085 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
1086 }
1087 }
1088 }
1089
1090 /* Check for NO error at all */
1091 if (!IsError && !TooHigh && !TooLow) {
1092 /* Set o.k. Status if no error and no warning condition */
1093 pSen->SenErrFlag = SK_SEN_ERR_OK;
1094 }
1095
1096 /* End of check against the thresholds */
1097
1098 /* Bug fix AF: 16.Aug.2001: Correct the init base
1099 * of LM80 sensor.
1100 */
1101 if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1102
1103 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1104
1105 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1106 /* 5V PCI-IO Voltage */
1107 pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1108 pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1109 }
1110 else {
1111 /* 3.3V PCI-IO Voltage */
1112 pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1113 pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1114 }
1115 }
1116
1117#ifdef TEST_ONLY
1118 /* Dynamic thresholds also for VAUX of LM80 sensor */
1119 if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1120
1121 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1122
1123 /* 3.3V VAUX Voltage */
1124 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1125 pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1126 pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1127 }
1128 /* 0V VAUX Voltage */
1129 else {
1130 pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1131 pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1132 }
1133 }
1134
1135 /*
1136 * Check initialization state:
1137 * The VIO Thresholds need adaption
1138 */
1139 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1140 pSen->SenValue > SK_SEN_WARNLOW2C &&
1141 pSen->SenValue < SK_SEN_WARNHIGH2) {
1142 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1143 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1144 pSen->SenInit = SK_TRUE;
1145 }
1146
1147 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1148 pSen->SenValue > SK_SEN_WARNLOW2 &&
1149 pSen->SenValue < SK_SEN_WARNHIGH2C) {
1150 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1151 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1152 pSen->SenInit = SK_TRUE;
1153 }
1154#endif
1155
1156 if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1157 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1158 }
1159} /* SkI2cCheckSensor */
1160
1161
1162/*
1163 * The only Event to be served is the timeout event
1164 *
1165 */
1166int SkI2cEvent(
1167SK_AC *pAC, /* Adapter Context */
1168SK_IOC IoC, /* I/O Context */
1169SK_U32 Event, /* Module specific Event */
1170SK_EVPARA Para) /* Event specific Parameter */
1171{
1172 int ReadComplete;
1173 SK_SENSOR *pSen;
1174 SK_U32 Time;
1175 SK_EVPARA ParaLocal;
1176 int i;
1177
1178 /* New case: no sensors */
1179 if (pAC->I2c.MaxSens == 0) {
1180 return(0);
1181 }
1182
1183 switch (Event) {
1184 case SK_I2CEV_IRQ:
1185 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1186 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1187
1188 if (ReadComplete) {
1189 /* Check sensor against defined thresholds */
1190 SkI2cCheckSensor(pAC, pSen);
1191
1192 /* Increment Current sensor and set appropriate Timeout */
1193 pAC->I2c.CurrSens++;
1194 if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1195 pAC->I2c.CurrSens = 0;
1196 Time = SK_I2C_TIM_LONG;
1197 }
1198 else {
1199 Time = SK_I2C_TIM_SHORT;
1200 }
1201
1202 /* Start Timer */
1203 ParaLocal.Para64 = (SK_U64)0;
1204
1205 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1206
1207 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1208 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1209 }
1210 else {
1211 /* Start Timer */
1212 ParaLocal.Para64 = (SK_U64)0;
1213
1214 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
1215
1216 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1217 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1218 }
1219 break;
1220 case SK_I2CEV_TIM:
1221 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1222
1223 ParaLocal.Para64 = (SK_U64)0;
1224 SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1225
1226 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1227 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1228
1229 if (ReadComplete) {
1230 /* Check sensor against defined thresholds */
1231 SkI2cCheckSensor(pAC, pSen);
1232
1233 /* Increment Current sensor and set appropriate Timeout */
1234 pAC->I2c.CurrSens++;
1235 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1236 pAC->I2c.CurrSens = 0;
1237 Time = SK_I2C_TIM_LONG;
1238 }
1239 else {
1240 Time = SK_I2C_TIM_SHORT;
1241 }
1242
1243 /* Start Timer */
1244 ParaLocal.Para64 = (SK_U64)0;
1245
1246 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1247
1248 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1249 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1250 }
1251 }
1252 else {
1253 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1254 pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1255 SK_I2C_STOP(IoC);
1256
1257 /* Increment Current sensor and set appropriate Timeout */
1258 pAC->I2c.CurrSens++;
1259 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1260 pAC->I2c.CurrSens = 0;
1261 Time = SK_I2C_TIM_LONG;
1262 }
1263 else {
1264 Time = SK_I2C_TIM_SHORT;
1265 }
1266
1267 /* Start Timer */
1268 ParaLocal.Para64 = (SK_U64)0;
1269
1270 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1271
1272 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1273 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1274 }
1275 break;
1276 case SK_I2CEV_CLEAR:
1277 for (i = 0; i < SK_MAX_SENSORS; i++) {
1278 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1279 pAC->I2c.SenTable[i].SenErrCts = 0;
1280 pAC->I2c.SenTable[i].SenWarnCts = 0;
1281 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1282 pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1283 pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1284 pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1285 pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1286 pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1287 }
1288 break;
1289 default:
1290 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1291 }
1292
1293 return(0);
1294} /* SkI2cEvent*/
1295
1296#endif /* !SK_DIAG */
diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c
deleted file mode 100644
index a204f5bb55d4..000000000000
--- a/drivers/net/sk98lin/sklm80.c
+++ /dev/null
@@ -1,141 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sklm80.c
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.22 $
6 * Date: $Date: 2003/10/20 09:08:21 $
7 * Purpose: Functions to access Voltage and Temperature Sensor (LM80)
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 LM80 functions
27*/
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/lm80.h"
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#define BREAK_OR_WAIT(pAC,IoC,Event) break
38
39/*
40 * read a sensors value (LM80 specific)
41 *
42 * This function reads a sensors value from the I2C sensor chip LM80.
43 * The sensor is defined by its index into the sensors database in the struct
44 * pAC points to.
45 *
46 * Returns 1 if the read is completed
47 * 0 if the read must be continued (I2C Bus still allocated)
48 */
49int SkLm80ReadSensor(
50SK_AC *pAC, /* Adapter Context */
51SK_IOC IoC, /* I/O Context needed in level 1 and 2 */
52SK_SENSOR *pSen) /* Sensor to be read */
53{
54 SK_I32 Value;
55
56 switch (pSen->SenState) {
57 case SK_SEN_IDLE:
58 /* Send address to ADDR register */
59 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0);
60
61 pSen->SenState = SK_SEN_VALUE ;
62 BREAK_OR_WAIT(pAC, IoC, I2C_READ);
63
64 case SK_SEN_VALUE:
65 /* Read value from data register */
66 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
67
68 Value &= 0xff; /* only least significant byte is valid */
69
70 /* Do NOT check the Value against the thresholds */
71 /* Checking is done in the calling instance */
72
73 if (pSen->SenType == SK_SEN_VOLT) {
74 /* Voltage sensor */
75 pSen->SenValue = Value * SK_LM80_VT_LSB;
76 pSen->SenState = SK_SEN_IDLE ;
77 return(1);
78 }
79
80 if (pSen->SenType == SK_SEN_FAN) {
81 if (Value != 0 && Value != 0xff) {
82 /* Fan speed counter */
83 pSen->SenValue = SK_LM80_FAN_FAKTOR/Value;
84 }
85 else {
86 /* Indicate Fan error */
87 pSen->SenValue = 0;
88 }
89 pSen->SenState = SK_SEN_IDLE ;
90 return(1);
91 }
92
93 /* First: correct the value: it might be negative */
94 if ((Value & 0x80) != 0) {
95 /* Value is negative */
96 Value = Value - 256;
97 }
98
99 /* We have a temperature sensor and need to get the signed extension.
100 * For now we get the extension from the last reading, so in the normal
101 * case we won't see flickering temperatures.
102 */
103 pSen->SenValue = (Value * SK_LM80_TEMP_LSB) +
104 (pSen->SenValue % SK_LM80_TEMP_LSB);
105
106 /* Send address to ADDR register */
107 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
108
109 pSen->SenState = SK_SEN_VALEXT ;
110 BREAK_OR_WAIT(pAC, IoC, I2C_READ);
111
112 case SK_SEN_VALEXT:
113 /* Read value from data register */
114 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
115 Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */
116
117 /* cut the LSB bit */
118 pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) *
119 SK_LM80_TEMP_LSB);
120
121 if (pSen->SenValue < 0) {
122 /* Value negative: The bit value must be subtracted */
123 pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
124 }
125 else {
126 /* Value positive: The bit value must be added */
127 pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
128 }
129
130 pSen->SenState = SK_SEN_IDLE ;
131 return(1);
132
133 default:
134 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG);
135 return(1);
136 }
137
138 /* Not completed */
139 return(0);
140}
141
diff --git a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
deleted file mode 100644
index 0275b4f71d9b..000000000000
--- a/drivers/net/sk98lin/skqueue.c
+++ /dev/null
@@ -1,179 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skqueue.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.20 $
6 * Date: $Date: 2003/09/16 13:44:00 $
7 * Purpose: Management of an event queue.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26/*
27 * Event queue and dispatcher
28 */
29#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
30static const char SysKonnectFileId[] =
31 "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
32#endif
33
34#include "h/skdrv1st.h" /* Driver Specific Definitions */
35#include "h/skqueue.h" /* Queue Definitions */
36#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
37
38#ifdef __C2MAN__
39/*
40 Event queue management.
41
42 General Description:
43
44 */
45intro()
46{}
47#endif
48
49#define PRINTF(a,b,c)
50
51/*
52 * init event queue management
53 *
54 * Must be called during init level 0.
55 */
56void SkEventInit(
57SK_AC *pAC, /* Adapter context */
58SK_IOC Ioc, /* IO context */
59int Level) /* Init level */
60{
61 switch (Level) {
62 case SK_INIT_DATA:
63 pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue;
64 break;
65 default:
66 break;
67 }
68}
69
70/*
71 * add event to queue
72 */
73void SkEventQueue(
74SK_AC *pAC, /* Adapters context */
75SK_U32 Class, /* Event Class */
76SK_U32 Event, /* Event to be queued */
77SK_EVPARA Para) /* Event parameter */
78{
79 pAC->Event.EvPut->Class = Class;
80 pAC->Event.EvPut->Event = Event;
81 pAC->Event.EvPut->Para = Para;
82
83 if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
84 pAC->Event.EvPut = pAC->Event.EvQueue;
85
86 if (pAC->Event.EvPut == pAC->Event.EvGet) {
87 SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
88 }
89}
90
91/*
92 * event dispatcher
93 * while event queue is not empty
94 * get event from queue
95 * send command to state machine
96 * end
97 * return error reported by individual Event function
98 * 0 if no error occured.
99 */
100int SkEventDispatcher(
101SK_AC *pAC, /* Adapters Context */
102SK_IOC Ioc) /* Io context */
103{
104 SK_EVENTELEM *pEv; /* pointer into queue */
105 SK_U32 Class;
106 int Rtv;
107
108 pEv = pAC->Event.EvGet;
109
110 PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
111
112 while (pEv != pAC->Event.EvPut) {
113 PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event);
114
115 switch (Class = pEv->Class) {
116#ifndef SK_USE_LAC_EV
117#ifndef SK_SLIM
118 case SKGE_RLMT: /* RLMT Event */
119 Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para);
120 break;
121 case SKGE_I2C: /* I2C Event */
122 Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para);
123 break;
124 case SKGE_PNMI: /* PNMI Event */
125 Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para);
126 break;
127#endif /* not SK_SLIM */
128#endif /* not SK_USE_LAC_EV */
129 case SKGE_DRV: /* Driver Event */
130 Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para);
131 break;
132#ifndef SK_USE_SW_TIMER
133 case SKGE_HWAC:
134 Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para);
135 break;
136#else /* !SK_USE_SW_TIMER */
137 case SKGE_SWT :
138 Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para);
139 break;
140#endif /* !SK_USE_SW_TIMER */
141#ifdef SK_USE_LAC_EV
142 case SKGE_LACP :
143 Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para);
144 break;
145 case SKGE_RSF :
146 Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para);
147 break;
148 case SKGE_MARKER :
149 Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para);
150 break;
151 case SKGE_FD :
152 Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
153 break;
154#endif /* SK_USE_LAC_EV */
155#ifdef SK_USE_CSUM
156 case SKGE_CSUM :
157 Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
158 break;
159#endif /* SK_USE_CSUM */
160 default :
161 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG);
162 Rtv = 0;
163 }
164
165 if (Rtv != 0) {
166 return(Rtv);
167 }
168
169 if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
170 pEv = pAC->Event.EvQueue;
171
172 /* Renew get: it is used in queue_events to detect overruns */
173 pAC->Event.EvGet = pEv;
174 }
175
176 return(0);
177}
178
179/* End of file */
diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c
deleted file mode 100644
index be8d1ccddf6d..000000000000
--- a/drivers/net/sk98lin/skrlmt.c
+++ /dev/null
@@ -1,3257 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skrlmt.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.69 $
6 * Date: $Date: 2003/04/15 09:39:22 $
7 * Purpose: Manage links on SK-NET Adapters, esp. redundant ones.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters.
30 * It is mainly intended for adapters with more than one link.
31 * For such adapters, this module realizes Redundant Link ManagemenT (RLMT).
32 *
33 * Include File Hierarchy:
34 *
35 * "skdrv1st.h"
36 * "skdrv2nd.h"
37 *
38 ******************************************************************************/
39
40#ifndef lint
41static const char SysKonnectFileId[] =
42 "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";
43#endif /* !defined(lint) */
44
45#define __SKRLMT_C
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51#include "h/skdrv1st.h"
52#include "h/skdrv2nd.h"
53
54/* defines ********************************************************************/
55
56#ifndef SK_HWAC_LINK_LED
57#define SK_HWAC_LINK_LED(a,b,c,d)
58#endif /* !defined(SK_HWAC_LINK_LED) */
59
60#ifndef DEBUG
61#define RLMT_STATIC static
62#else /* DEBUG */
63#define RLMT_STATIC
64
65#ifndef SK_LITTLE_ENDIAN
66/* First 32 bits */
67#define OFFS_LO32 1
68
69/* Second 32 bits */
70#define OFFS_HI32 0
71#else /* SK_LITTLE_ENDIAN */
72/* First 32 bits */
73#define OFFS_LO32 0
74
75/* Second 32 bits */
76#define OFFS_HI32 1
77#endif /* SK_LITTLE_ENDIAN */
78
79#endif /* DEBUG */
80
81/* ----- Private timeout values ----- */
82
83#define SK_RLMT_MIN_TO_VAL 125000 /* 1/8 sec. */
84#define SK_RLMT_DEF_TO_VAL 1000000 /* 1 sec. */
85#define SK_RLMT_PORTDOWN_TIM_VAL 900000 /* another 0.9 sec. */
86#define SK_RLMT_PORTSTART_TIM_VAL 100000 /* 0.1 sec. */
87#define SK_RLMT_PORTUP_TIM_VAL 2500000 /* 2.5 sec. */
88#define SK_RLMT_SEG_TO_VAL 900000000 /* 15 min. */
89
90/* Assume tick counter increment is 1 - may be set OS-dependent. */
91#ifndef SK_TICK_INCR
92#define SK_TICK_INCR SK_CONSTU64(1)
93#endif /* !defined(SK_TICK_INCR) */
94
95/*
96 * Amount that a time stamp must be later to be recognized as "substantially
97 * later". This is about 1/128 sec, but above 1 tick counter increment.
98 */
99#define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
100 (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
101
102/* ----- Private RLMT defaults ----- */
103
104#define SK_RLMT_DEF_PREF_PORT 0 /* "Lower" port. */
105#define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK /* Default RLMT Mode. */
106
107/* ----- Private RLMT checking states ----- */
108
109#define SK_RLMT_RCS_SEG 1 /* RLMT Check State: check seg. */
110#define SK_RLMT_RCS_START_SEG 2 /* RLMT Check State: start check seg. */
111#define SK_RLMT_RCS_SEND_SEG 4 /* RLMT Check State: send BPDU packet */
112#define SK_RLMT_RCS_REPORT_SEG 8 /* RLMT Check State: report seg. */
113
114/* ----- Private PORT checking states ----- */
115
116#define SK_RLMT_PCS_TX 1 /* Port Check State: check tx. */
117#define SK_RLMT_PCS_RX 2 /* Port Check State: check rx. */
118
119/* ----- Private PORT events ----- */
120
121/* Note: Update simulation when changing these. */
122#define SK_RLMT_PORTSTART_TIM 1100 /* Port start timeout. */
123#define SK_RLMT_PORTUP_TIM 1101 /* Port can now go up. */
124#define SK_RLMT_PORTDOWN_RX_TIM 1102 /* Port did not receive once ... */
125#define SK_RLMT_PORTDOWN 1103 /* Port went down. */
126#define SK_RLMT_PORTDOWN_TX_TIM 1104 /* Partner did not receive ... */
127
128/* ----- Private RLMT events ----- */
129
130/* Note: Update simulation when changing these. */
131#define SK_RLMT_TIM 2100 /* RLMT timeout. */
132#define SK_RLMT_SEG_TIM 2101 /* RLMT segmentation check timeout. */
133
134#define TO_SHORTEN(tim) ((tim) / 2)
135
136/* Error numbers and messages. */
137#define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0)
138#define SKERR_RLMT_E001_MSG "No Packet."
139#define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1)
140#define SKERR_RLMT_E002_MSG "Short Packet."
141#define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1)
142#define SKERR_RLMT_E003_MSG "Unknown RLMT event."
143#define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1)
144#define SKERR_RLMT_E004_MSG "PortsUp incorrect."
145#define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1)
146#define SKERR_RLMT_E005_MSG \
147 "Net seems to be segmented (different root bridges are reported on the ports)."
148#define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1)
149#define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected."
150#define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1)
151#define SKERR_RLMT_E007_MSG "LinksUp incorrect."
152#define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1)
153#define SKERR_RLMT_E008_MSG "Port not started but link came up."
154#define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1)
155#define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port."
156#define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1)
157#define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port."
158
159/* LLC field values. */
160#define LLC_COMMAND_RESPONSE_BIT 1
161#define LLC_TEST_COMMAND 0xE3
162#define LLC_UI 0x03
163
164/* RLMT Packet fields. */
165#define SK_RLMT_DSAP 0
166#define SK_RLMT_SSAP 0
167#define SK_RLMT_CTRL (LLC_TEST_COMMAND)
168#define SK_RLMT_INDICATOR0 0x53 /* S */
169#define SK_RLMT_INDICATOR1 0x4B /* K */
170#define SK_RLMT_INDICATOR2 0x2D /* - */
171#define SK_RLMT_INDICATOR3 0x52 /* R */
172#define SK_RLMT_INDICATOR4 0x4C /* L */
173#define SK_RLMT_INDICATOR5 0x4D /* M */
174#define SK_RLMT_INDICATOR6 0x54 /* T */
175#define SK_RLMT_PACKET_VERSION 0
176
177/* RLMT SPT Flag values. */
178#define SK_RLMT_SPT_FLAG_CHANGE 0x01
179#define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80
180
181/* RLMT SPT Packet fields. */
182#define SK_RLMT_SPT_DSAP 0x42
183#define SK_RLMT_SPT_SSAP 0x42
184#define SK_RLMT_SPT_CTRL (LLC_UI)
185#define SK_RLMT_SPT_PROTOCOL_ID0 0x00
186#define SK_RLMT_SPT_PROTOCOL_ID1 0x00
187#define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
188#define SK_RLMT_SPT_BPDU_TYPE 0x00
189#define SK_RLMT_SPT_FLAGS 0x00 /* ?? */
190#define SK_RLMT_SPT_ROOT_ID0 0xFF /* Lowest possible priority. */
191#define SK_RLMT_SPT_ROOT_ID1 0xFF /* Lowest possible priority. */
192
193/* Remaining 6 bytes will be the current port address. */
194#define SK_RLMT_SPT_ROOT_PATH_COST0 0x00
195#define SK_RLMT_SPT_ROOT_PATH_COST1 0x00
196#define SK_RLMT_SPT_ROOT_PATH_COST2 0x00
197#define SK_RLMT_SPT_ROOT_PATH_COST3 0x00
198#define SK_RLMT_SPT_BRIDGE_ID0 0xFF /* Lowest possible priority. */
199#define SK_RLMT_SPT_BRIDGE_ID1 0xFF /* Lowest possible priority. */
200
201/* Remaining 6 bytes will be the current port address. */
202#define SK_RLMT_SPT_PORT_ID0 0xFF /* Lowest possible priority. */
203#define SK_RLMT_SPT_PORT_ID1 0xFF /* Lowest possible priority. */
204#define SK_RLMT_SPT_MSG_AGE0 0x00
205#define SK_RLMT_SPT_MSG_AGE1 0x00
206#define SK_RLMT_SPT_MAX_AGE0 0x00
207#define SK_RLMT_SPT_MAX_AGE1 0xFF
208#define SK_RLMT_SPT_HELLO_TIME0 0x00
209#define SK_RLMT_SPT_HELLO_TIME1 0xFF
210#define SK_RLMT_SPT_FWD_DELAY0 0x00
211#define SK_RLMT_SPT_FWD_DELAY1 0x40
212
213/* Size defines. */
214#define SK_RLMT_MIN_PACKET_SIZE 34
215#define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE)
216#define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \
217 SK_RLMT_MIN_PACKET_SIZE)
218
219/* ----- RLMT packet types ----- */
220#define SK_PACKET_ANNOUNCE 1 /* Port announcement. */
221#define SK_PACKET_ALIVE 2 /* Alive packet to port. */
222#define SK_PACKET_ADDR_CHANGED 3 /* Port address changed. */
223#define SK_PACKET_CHECK_TX 4 /* Check your tx line. */
224
225#ifdef SK_LITTLE_ENDIAN
226#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
227 SK_U8 *_Addr = (SK_U8*)(Addr); \
228 SK_U16 _Val = (SK_U16)(Val); \
229 *_Addr++ = (SK_U8)(_Val >> 8); \
230 *_Addr = (SK_U8)(_Val & 0xFF); \
231}
232#endif /* SK_LITTLE_ENDIAN */
233
234#ifdef SK_BIG_ENDIAN
235#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
236#endif /* SK_BIG_ENDIAN */
237
238#define AUTONEG_FAILED SK_FALSE
239#define AUTONEG_SUCCESS SK_TRUE
240
241
242/* typedefs *******************************************************************/
243
244/* RLMT packet. Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
245typedef struct s_RlmtPacket {
246 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
247 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
248 SK_U8 TypeLen[2];
249 SK_U8 DSap;
250 SK_U8 SSap;
251 SK_U8 Ctrl;
252 SK_U8 Indicator[7];
253 SK_U8 RlmtPacketType[2];
254 SK_U8 Align1[2];
255 SK_U8 Random[4]; /* Random value of requesting(!) station. */
256 SK_U8 RlmtPacketVersion[2]; /* RLMT Packet version. */
257 SK_U8 Data[SK_PACKET_DATA_LEN];
258} SK_RLMT_PACKET;
259
260typedef struct s_SpTreeRlmtPacket {
261 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
262 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
263 SK_U8 TypeLen[2];
264 SK_U8 DSap;
265 SK_U8 SSap;
266 SK_U8 Ctrl;
267 SK_U8 ProtocolId[2];
268 SK_U8 ProtocolVersionId;
269 SK_U8 BpduType;
270 SK_U8 Flags;
271 SK_U8 RootId[8];
272 SK_U8 RootPathCost[4];
273 SK_U8 BridgeId[8];
274 SK_U8 PortId[2];
275 SK_U8 MessageAge[2];
276 SK_U8 MaxAge[2];
277 SK_U8 HelloTime[2];
278 SK_U8 ForwardDelay[2];
279} SK_SPTREE_PACKET;
280
281/* global variables ***********************************************************/
282
283SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}};
284SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}};
285
286/* local variables ************************************************************/
287
288/* None. */
289
290/* functions ******************************************************************/
291
292RLMT_STATIC void SkRlmtCheckSwitch(
293 SK_AC *pAC,
294 SK_IOC IoC,
295 SK_U32 NetIdx);
296RLMT_STATIC void SkRlmtCheckSeg(
297 SK_AC *pAC,
298 SK_IOC IoC,
299 SK_U32 NetIdx);
300RLMT_STATIC void SkRlmtEvtSetNets(
301 SK_AC *pAC,
302 SK_IOC IoC,
303 SK_EVPARA Para);
304
305/******************************************************************************
306 *
307 * SkRlmtInit - initialize data, set state to init
308 *
309 * Description:
310 *
311 * SK_INIT_DATA
312 * ============
313 *
314 * This routine initializes all RLMT-related variables to a known state.
315 * The initial state is SK_RLMT_RS_INIT.
316 * All ports are initialized to SK_RLMT_PS_INIT.
317 *
318 *
319 * SK_INIT_IO
320 * ==========
321 *
322 * Nothing.
323 *
324 *
325 * SK_INIT_RUN
326 * ===========
327 *
328 * Determine the adapter's random value.
329 * Set the hw registers, the "logical MAC address", the
330 * RLMT multicast address, and eventually the BPDU multicast address.
331 *
332 * Context:
333 * init, pageable
334 *
335 * Returns:
336 * Nothing.
337 */
338void SkRlmtInit(
339SK_AC *pAC, /* Adapter Context */
340SK_IOC IoC, /* I/O Context */
341int Level) /* Initialization Level */
342{
343 SK_U32 i, j;
344 SK_U64 Random;
345 SK_EVPARA Para;
346 SK_MAC_ADDR VirtualMacAddress;
347 SK_MAC_ADDR PhysicalAMacAddress;
348 SK_BOOL VirtualMacAddressSet;
349 SK_BOOL PhysicalAMacAddressSet;
350
351 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
352 ("RLMT Init level %d.\n", Level))
353
354 switch (Level) {
355 case SK_INIT_DATA: /* Initialize data structures. */
356 SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
357
358 for (i = 0; i < SK_MAX_MACS; i++) {
359 pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
360 pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
361 pAC->Rlmt.Port[i].PortDown = SK_TRUE;
362 pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
363 pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
364 pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
365 pAC->Rlmt.Port[i].PortNumber = i;
366 pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
367 pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
368 }
369
370 pAC->Rlmt.NumNets = 1;
371 for (i = 0; i < SK_MAX_NETS; i++) {
372 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
373 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
374 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
375 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */
376 /* Just assuming. */
377 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
378 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
379 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
380 pAC->Rlmt.Net[i].NetNumber = i;
381 }
382
383 pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
384 pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
385#if SK_MAX_NETS > 1
386 pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
387#endif /* SK_MAX_NETS > 1 */
388 break;
389
390 case SK_INIT_IO: /* GIMacsFound first available here. */
391 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
392 ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
393
394 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
395
396 /* Initialize HW registers? */
397 if (pAC->GIni.GIMacsFound == 1) {
398 Para.Para32[0] = SK_RLMT_MODE_CLS;
399 Para.Para32[1] = 0;
400 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
401 }
402 break;
403
404 case SK_INIT_RUN:
405 /* Ensure RLMT is set to one net. */
406 if (pAC->Rlmt.NumNets > 1) {
407 Para.Para32[0] = 1;
408 Para.Para32[1] = -1;
409 SkRlmtEvtSetNets(pAC, IoC, Para);
410 }
411
412 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
413 Random = SkOsGetTime(pAC);
414 *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
415
416 for (j = 0; j < 4; j++) {
417 pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
418 CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
419 }
420
421 (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
422
423 /* Add RLMT MC address. */
424 (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
425
426 if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
427 /* Add BPDU MC address. */
428 (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
429 }
430
431 (void)SkAddrMcUpdate(pAC, IoC, i);
432 }
433
434 VirtualMacAddressSet = SK_FALSE;
435 /* Read virtual MAC address from Control Register File. */
436 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
437
438 SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
439 VirtualMacAddressSet |= VirtualMacAddress.a[j];
440 }
441
442 PhysicalAMacAddressSet = SK_FALSE;
443 /* Read physical MAC address for MAC A from Control Register File. */
444 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
445
446 SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
447 PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
448 }
449
450 /* check if the two mac addresses contain reasonable values */
451 if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
452
453 pAC->Rlmt.RlmtOff = SK_TRUE;
454 }
455
456 /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD
457 and the RLMT_LOOKAHEAD macros */
458 else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
459
460 pAC->Rlmt.RlmtOff = SK_TRUE;
461 }
462 else {
463 pAC->Rlmt.RlmtOff = SK_FALSE;
464 }
465 break;
466
467 default: /* error */
468 break;
469 }
470 return;
471} /* SkRlmtInit */
472
473
474/******************************************************************************
475 *
476 * SkRlmtBuildCheckChain - build the check chain
477 *
478 * Description:
479 * This routine builds the local check chain:
480 * - Each port that is up checks the next port.
481 * - The last port that is up checks the first port that is up.
482 *
483 * Notes:
484 * - Currently only local ports are considered when building the chain.
485 * - Currently the SuspectState is just reset;
486 * it would be better to save it ...
487 *
488 * Context:
489 * runtime, pageable?
490 *
491 * Returns:
492 * Nothing
493 */
494RLMT_STATIC void SkRlmtBuildCheckChain(
495SK_AC *pAC, /* Adapter Context */
496SK_U32 NetIdx) /* Net Number */
497{
498 SK_U32 i;
499 SK_U32 NumMacsUp;
500 SK_RLMT_PORT * FirstMacUp;
501 SK_RLMT_PORT * PrevMacUp;
502
503 FirstMacUp = NULL;
504 PrevMacUp = NULL;
505
506 if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
507 for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
508 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
509 }
510 return; /* Done. */
511 }
512
513 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
514 ("SkRlmtBuildCheckChain.\n"))
515
516 NumMacsUp = 0;
517
518 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
519 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
520 pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
521 pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
522 ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
523
524 /*
525 * If more than two links are detected we should consider
526 * checking at least two other ports:
527 * 1. the next port that is not LinkDown and
528 * 2. the next port that is not PortDown.
529 */
530 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
531 if (NumMacsUp == 0) {
532 FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
533 }
534 else {
535 PrevMacUp->PortCheck[
536 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
537 pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
538 PrevMacUp->PortCheck[
539 PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
540 PrevMacUp->PortsChecked++;
541 }
542 PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
543 NumMacsUp++;
544 }
545 }
546
547 if (NumMacsUp > 1) {
548 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
549 FirstMacUp->AddrPort->CurrentMacAddress;
550 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
551 SK_FALSE;
552 PrevMacUp->PortsChecked++;
553 }
554
555#ifdef DEBUG
556 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
557 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
558 ("Port %d checks %d other ports: %2X.\n", i,
559 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
560 pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
561 }
562#endif /* DEBUG */
563
564 return;
565} /* SkRlmtBuildCheckChain */
566
567
568/******************************************************************************
569 *
570 * SkRlmtBuildPacket - build an RLMT packet
571 *
572 * Description:
573 * This routine sets up an RLMT packet.
574 *
575 * Context:
576 * runtime, pageable?
577 *
578 * Returns:
579 * NULL or pointer to RLMT mbuf
580 */
581RLMT_STATIC SK_MBUF *SkRlmtBuildPacket(
582SK_AC *pAC, /* Adapter Context */
583SK_IOC IoC, /* I/O Context */
584SK_U32 PortNumber, /* Sending port */
585SK_U16 PacketType, /* RLMT packet type */
586SK_MAC_ADDR *SrcAddr, /* Source address */
587SK_MAC_ADDR *DestAddr) /* Destination address */
588{
589 int i;
590 SK_U16 Length;
591 SK_MBUF *pMb;
592 SK_RLMT_PACKET *pPacket;
593
594#ifdef DEBUG
595 SK_U8 CheckSrc = 0;
596 SK_U8 CheckDest = 0;
597
598 for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
599 CheckSrc |= SrcAddr->a[i];
600 CheckDest |= DestAddr->a[i];
601 }
602
603 if ((CheckSrc == 0) || (CheckDest == 0)) {
604 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
605 ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
606 (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
607 }
608#endif
609
610 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
611 pPacket = (SK_RLMT_PACKET*)pMb->pData;
612 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
613 pPacket->DstAddr[i] = DestAddr->a[i];
614 pPacket->SrcAddr[i] = SrcAddr->a[i];
615 }
616 pPacket->DSap = SK_RLMT_DSAP;
617 pPacket->SSap = SK_RLMT_SSAP;
618 pPacket->Ctrl = SK_RLMT_CTRL;
619 pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
620 pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
621 pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
622 pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
623 pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
624 pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
625 pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
626
627 SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
628
629 for (i = 0; i < 4; i++) {
630 pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
631 }
632
633 SK_U16_TO_NETWORK_ORDER(
634 SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
635
636 for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
637 pPacket->Data[i] = 0x00;
638 }
639
640 Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
641 pMb->Length = Length;
642 pMb->PortIdx = PortNumber;
643 Length -= 14;
644 SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
645
646 if (PacketType == SK_PACKET_ALIVE) {
647 pAC->Rlmt.Port[PortNumber].TxHelloCts++;
648 }
649 }
650
651 return (pMb);
652} /* SkRlmtBuildPacket */
653
654
655/******************************************************************************
656 *
657 * SkRlmtBuildSpanningTreePacket - build spanning tree check packet
658 *
659 * Description:
660 * This routine sets up a BPDU packet for spanning tree check.
661 *
662 * Context:
663 * runtime, pageable?
664 *
665 * Returns:
666 * NULL or pointer to RLMT mbuf
667 */
668RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket(
669SK_AC *pAC, /* Adapter Context */
670SK_IOC IoC, /* I/O Context */
671SK_U32 PortNumber) /* Sending port */
672{
673 unsigned i;
674 SK_U16 Length;
675 SK_MBUF *pMb;
676 SK_SPTREE_PACKET *pSPacket;
677
678 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
679 NULL) {
680 pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
681 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
682 pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
683 pSPacket->SrcAddr[i] =
684 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
685 }
686 pSPacket->DSap = SK_RLMT_SPT_DSAP;
687 pSPacket->SSap = SK_RLMT_SPT_SSAP;
688 pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
689
690 pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
691 pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
692 pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
693 pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
694 pSPacket->Flags = SK_RLMT_SPT_FLAGS;
695 pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
696 pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
697 pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
698 pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
699 pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
700 pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
701 pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
702 pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
703
704 /*
705 * Use logical MAC address as bridge ID and filter these packets
706 * on receive.
707 */
708 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
709 pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
710 pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
711 CurrentMacAddress.a[i];
712 }
713 pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
714 pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
715 pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
716 pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
717 pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
718 pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
719 pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
720 pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
721 pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
722 pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
723
724 Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
725 pMb->Length = Length;
726 pMb->PortIdx = PortNumber;
727 Length -= 14;
728 SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
729
730 pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
731 }
732
733 return (pMb);
734} /* SkRlmtBuildSpanningTreePacket */
735
736
737/******************************************************************************
738 *
739 * SkRlmtSend - build and send check packets
740 *
741 * Description:
742 * Depending on the RLMT state and the checking state, several packets
743 * are sent through the indicated port.
744 *
745 * Context:
746 * runtime, pageable?
747 *
748 * Returns:
749 * Nothing.
750 */
751RLMT_STATIC void SkRlmtSend(
752SK_AC *pAC, /* Adapter Context */
753SK_IOC IoC, /* I/O Context */
754SK_U32 PortNumber) /* Sending port */
755{
756 unsigned j;
757 SK_EVPARA Para;
758 SK_RLMT_PORT *pRPort;
759
760 pRPort = &pAC->Rlmt.Port[PortNumber];
761 if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
762 if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
763 /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
764 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
765 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
766 &SkRlmtMcAddr)) != NULL) {
767 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
768 }
769 }
770 else {
771 /*
772 * Send a directed RLMT packet to all ports that are
773 * checked by the indicated port.
774 */
775 for (j = 0; j < pRPort->PortsChecked; j++) {
776 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
777 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
778 &pRPort->PortCheck[j].CheckAddr)) != NULL) {
779 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
780 }
781 }
782 }
783 }
784
785 if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
786 (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
787 /*
788 * Send a BPDU packet to make a connected switch tell us
789 * the correct root bridge.
790 */
791 if ((Para.pParaPtr =
792 SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
793 pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
794 pRPort->RootIdSet = SK_FALSE;
795
796 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
797 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
798 ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
799 }
800 }
801 return;
802} /* SkRlmtSend */
803
804
805/******************************************************************************
806 *
807 * SkRlmtPortReceives - check if port is (going) down and bring it up
808 *
809 * Description:
810 * This routine checks if a port who received a non-BPDU packet
811 * needs to go up or needs to be stopped going down.
812 *
813 * Context:
814 * runtime, pageable?
815 *
816 * Returns:
817 * Nothing.
818 */
819RLMT_STATIC void SkRlmtPortReceives(
820SK_AC *pAC, /* Adapter Context */
821SK_IOC IoC, /* I/O Context */
822SK_U32 PortNumber) /* Port to check */
823{
824 SK_RLMT_PORT *pRPort;
825 SK_EVPARA Para;
826
827 pRPort = &pAC->Rlmt.Port[PortNumber];
828 pRPort->PortNoRx = SK_FALSE;
829
830 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
831 !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
832 /*
833 * Port is marked down (rx), but received a non-BPDU packet.
834 * Bring it up.
835 */
836 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
837 ("SkRlmtPacketReceive: Received on PortDown.\n"))
838
839 pRPort->PortState = SK_RLMT_PS_GOING_UP;
840 pRPort->GuTimeStamp = SkOsGetTime(pAC);
841 Para.Para32[0] = PortNumber;
842 Para.Para32[1] = (SK_U32)-1;
843 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
844 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
845 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
846 /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
847 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
848 } /* PortDown && !SuspectTx */
849 else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
850 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
851 ("SkRlmtPacketReceive: Stop bringing port down.\n"))
852 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
853 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
854 /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
855 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
856 } /* PortGoingDown */
857
858 return;
859} /* SkRlmtPortReceives */
860
861
862/******************************************************************************
863 *
864 * SkRlmtPacketReceive - receive a packet for closer examination
865 *
866 * Description:
867 * This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
868 *
869 * Context:
870 * runtime, pageable?
871 *
872 * Returns:
873 * Nothing.
874 */
875RLMT_STATIC void SkRlmtPacketReceive(
876SK_AC *pAC, /* Adapter Context */
877SK_IOC IoC, /* I/O Context */
878SK_MBUF *pMb) /* Received packet */
879{
880#ifdef xDEBUG
881 extern void DumpData(char *p, int size);
882#endif /* DEBUG */
883 int i;
884 unsigned j;
885 SK_U16 PacketType;
886 SK_U32 PortNumber;
887 SK_ADDR_PORT *pAPort;
888 SK_RLMT_PORT *pRPort;
889 SK_RLMT_PACKET *pRPacket;
890 SK_SPTREE_PACKET *pSPacket;
891 SK_EVPARA Para;
892
893 PortNumber = pMb->PortIdx;
894 pAPort = &pAC->Addr.Port[PortNumber];
895 pRPort = &pAC->Rlmt.Port[PortNumber];
896
897 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
898 ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
899
900 pRPacket = (SK_RLMT_PACKET*)pMb->pData;
901 pSPacket = (SK_SPTREE_PACKET*)pRPacket;
902
903#ifdef xDEBUG
904 DumpData((char *)pRPacket, 32);
905#endif /* DEBUG */
906
907 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
908 SkRlmtPortReceives(pAC, IoC, PortNumber);
909 }
910
911 /* Check destination address. */
912
913 if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
914 !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
915 !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
916
917 /* Not sent to current MAC or registered MC address => Trash it. */
918 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
919 ("SkRlmtPacketReceive: Not for me.\n"))
920
921 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
922 return;
923 }
924 else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
925
926 /*
927 * Was sent by same port (may happen during port switching
928 * or in case of duplicate MAC addresses).
929 */
930
931 /*
932 * Check for duplicate address here:
933 * If Packet.Random != My.Random => DupAddr.
934 */
935 for (i = 3; i >= 0; i--) {
936 if (pRPort->Random[i] != pRPacket->Random[i]) {
937 break;
938 }
939 }
940
941 /*
942 * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
943 * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
944 * pRPacket->SSap).
945 */
946 if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
947 pRPacket->Ctrl == SK_RLMT_CTRL &&
948 pRPacket->SSap == SK_RLMT_SSAP &&
949 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
950 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
951 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
952 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
953 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
954 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
955 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
956 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
957 ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
958
959 /* Error Log entry. */
960 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
961 }
962 else {
963 /* Simply trash it. */
964 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
965 ("SkRlmtPacketReceive: Sent by me.\n"))
966 }
967
968 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
969 return;
970 }
971
972 /* Check SuspectTx entries. */
973 if (pRPort->PortsSuspect > 0) {
974 for (j = 0; j < pRPort->PortsChecked; j++) {
975 if (pRPort->PortCheck[j].SuspectTx &&
976 SK_ADDR_EQUAL(
977 pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
978 pRPort->PortCheck[j].SuspectTx = SK_FALSE;
979 pRPort->PortsSuspect--;
980 break;
981 }
982 }
983 }
984
985 /* Determine type of packet. */
986 if (pRPacket->DSap == SK_RLMT_DSAP &&
987 pRPacket->Ctrl == SK_RLMT_CTRL &&
988 (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
989 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
990 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
991 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
992 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
993 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
994 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
995 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
996
997 /* It's an RLMT packet. */
998 PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
999 pRPacket->RlmtPacketType[1]);
1000
1001 switch (PacketType) {
1002 case SK_PACKET_ANNOUNCE: /* Not yet used. */
1003#if 0
1004 /* Build the check chain. */
1005 SkRlmtBuildCheckChain(pAC);
1006#endif /* 0 */
1007
1008 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1009 ("SkRlmtPacketReceive: Announce.\n"))
1010
1011 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1012 break;
1013
1014 case SK_PACKET_ALIVE:
1015 if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
1016 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1017 ("SkRlmtPacketReceive: Alive Reply.\n"))
1018
1019 if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
1020 SK_ADDR_EQUAL(
1021 pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
1022 /* Obviously we could send something. */
1023 if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
1024 pRPort->CheckingState &= ~SK_RLMT_PCS_TX;
1025 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1026 }
1027
1028 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
1029 !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1030 pRPort->PortState = SK_RLMT_PS_GOING_UP;
1031 pRPort->GuTimeStamp = SkOsGetTime(pAC);
1032
1033 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1034
1035 Para.Para32[0] = PortNumber;
1036 Para.Para32[1] = (SK_U32)-1;
1037 SkTimerStart(pAC, IoC, &pRPort->UpTimer,
1038 SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
1039 SK_RLMT_PORTUP_TIM, Para);
1040 }
1041 }
1042
1043 /* Mark sending port as alive? */
1044 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1045 }
1046 else { /* Alive Request Packet. */
1047 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1048 ("SkRlmtPacketReceive: Alive Request.\n"))
1049
1050 pRPort->RxHelloCts++;
1051
1052 /* Answer. */
1053 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
1054 pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
1055 pRPacket->SrcAddr[i] =
1056 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
1057 }
1058 pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
1059
1060 Para.pParaPtr = pMb;
1061 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1062 }
1063 break;
1064
1065 case SK_PACKET_CHECK_TX:
1066 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1067 ("SkRlmtPacketReceive: Check your tx line.\n"))
1068
1069 /* A port checking us requests us to check our tx line. */
1070 pRPort->CheckingState |= SK_RLMT_PCS_TX;
1071
1072 /* Start PortDownTx timer. */
1073 Para.Para32[0] = PortNumber;
1074 Para.Para32[1] = (SK_U32)-1;
1075 SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
1076 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1077 SK_RLMT_PORTDOWN_TX_TIM, Para);
1078
1079 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1080
1081 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
1082 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1083 &SkRlmtMcAddr)) != NULL) {
1084 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1085 }
1086 break;
1087
1088 case SK_PACKET_ADDR_CHANGED:
1089 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1090 ("SkRlmtPacketReceive: Address Change.\n"))
1091
1092 /* Build the check chain. */
1093 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
1094 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1095 break;
1096
1097 default:
1098 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1099 ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
1100
1101 /* RA;:;: ??? */
1102 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1103 }
1104 }
1105 else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
1106 pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
1107 (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
1108 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1109 ("SkRlmtPacketReceive: BPDU Packet.\n"))
1110
1111 /* Spanning Tree packet. */
1112 pRPort->RxSpHelloCts++;
1113
1114 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
1115 Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
1116 /*
1117 * Check segmentation if a new root bridge is set and
1118 * the segmentation check is not currently running.
1119 */
1120 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
1121 (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1122 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
1123 != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1124 SK_RLMT_RCS_SEG) == 0) {
1125 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1126 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1127 }
1128
1129 /* Store tree view of this port. */
1130 for (i = 0; i < 8; i++) {
1131 pRPort->Root.Id[i] = pSPacket->RootId[i];
1132 }
1133 pRPort->RootIdSet = SK_TRUE;
1134
1135 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
1136 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
1137 PortNumber,
1138 pRPort->Root.Id[0], pRPort->Root.Id[1],
1139 pRPort->Root.Id[2], pRPort->Root.Id[3],
1140 pRPort->Root.Id[4], pRPort->Root.Id[5],
1141 pRPort->Root.Id[6], pRPort->Root.Id[7]))
1142 }
1143
1144 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1145 if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1146 SK_RLMT_RCS_REPORT_SEG) != 0) {
1147 SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
1148 }
1149 }
1150 else {
1151 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1152 ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
1153
1154 /* Unknown packet. */
1155 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1156 }
1157 return;
1158} /* SkRlmtPacketReceive */
1159
1160
1161/******************************************************************************
1162 *
1163 * SkRlmtCheckPort - check if a port works
1164 *
1165 * Description:
1166 * This routine checks if a port whose link is up received something
1167 * and if it seems to transmit successfully.
1168 *
1169 * # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp
1170 * # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg
1171 * # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg
1172 *
1173 * if (Rx - RxBpdu == 0) { # No rx.
1174 * if (state == PsUp) {
1175 * PortCheckingState |= ChkRx
1176 * }
1177 * if (ModeCheckSeg && (Timeout ==
1178 * TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) {
1179 * RlmtCheckingState |= ChkSeg)
1180 * PortCheckingState |= ChkSeg
1181 * }
1182 * NewTimeout = TO_SHORTEN(Timeout)
1183 * if (NewTimeout < RLMT_MIN_TIMEOUT) {
1184 * NewTimeout = RLMT_MIN_TIMEOUT
1185 * PortState = PsDown
1186 * ...
1187 * }
1188 * }
1189 * else { # something was received
1190 * # Set counter to 0 at LinkDown?
1191 * # No - rx may be reported after LinkDown ???
1192 * PortCheckingState &= ~ChkRx
1193 * NewTimeout = RLMT_DEFAULT_TIMEOUT
1194 * if (RxAck == 0) {
1195 * possible reasons:
1196 * is my tx line bad? --
1197 * send RLMT multicast and report
1198 * back internally? (only possible
1199 * between ports on same adapter)
1200 * }
1201 * if (RxChk == 0) {
1202 * possible reasons:
1203 * - tx line of port set to check me
1204 * maybe bad
1205 * - no other port/adapter available or set
1206 * to check me
1207 * - adapter checking me has a longer
1208 * timeout
1209 * ??? anything that can be done here?
1210 * }
1211 * }
1212 *
1213 * Context:
1214 * runtime, pageable?
1215 *
1216 * Returns:
1217 * New timeout value.
1218 */
1219RLMT_STATIC SK_U32 SkRlmtCheckPort(
1220SK_AC *pAC, /* Adapter Context */
1221SK_IOC IoC, /* I/O Context */
1222SK_U32 PortNumber) /* Port to check */
1223{
1224 unsigned i;
1225 SK_U32 NewTimeout;
1226 SK_RLMT_PORT *pRPort;
1227 SK_EVPARA Para;
1228
1229 pRPort = &pAC->Rlmt.Port[PortNumber];
1230
1231 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
1232 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1233 ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
1234 PortNumber, pRPort->PacketsPerTimeSlot))
1235
1236 /*
1237 * Check segmentation if there was no receive at least twice
1238 * in a row (PortNoRx is already set) and the segmentation
1239 * check is not currently running.
1240 */
1241
1242 if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1243 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
1244 !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
1245 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1246 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1247 }
1248
1249 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1250 ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
1251 pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
1252
1253 if (pRPort->PortState != SK_RLMT_PS_DOWN) {
1254 NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
1255 if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
1256 NewTimeout = SK_RLMT_MIN_TO_VAL;
1257 }
1258
1259 if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1260 Para.Para32[0] = PortNumber;
1261 pRPort->CheckingState |= SK_RLMT_PCS_RX;
1262
1263 /*
1264 * What shall we do if the port checked by this one receives
1265 * our request frames? What's bad - our rx line or his tx line?
1266 */
1267 Para.Para32[1] = (SK_U32)-1;
1268 SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
1269 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1270 SK_RLMT_PORTDOWN_RX_TIM, Para);
1271
1272 for (i = 0; i < pRPort->PortsChecked; i++) {
1273 if (pRPort->PortCheck[i].SuspectTx) {
1274 continue;
1275 }
1276 pRPort->PortCheck[i].SuspectTx = SK_TRUE;
1277 pRPort->PortsSuspect++;
1278 if ((Para.pParaPtr =
1279 SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
1280 &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1281 &pRPort->PortCheck[i].CheckAddr)) != NULL) {
1282 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1283 }
1284 }
1285 }
1286 }
1287 else { /* PortDown -- or all partners suspect. */
1288 NewTimeout = SK_RLMT_DEF_TO_VAL;
1289 }
1290 pRPort->PortNoRx = SK_TRUE;
1291 }
1292 else { /* A non-BPDU packet was received. */
1293 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1294 ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
1295 PortNumber,
1296 pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
1297 pRPort->PacketsPerTimeSlot))
1298
1299 SkRlmtPortReceives(pAC, IoC, PortNumber);
1300 if (pAC->Rlmt.CheckSwitch) {
1301 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
1302 }
1303
1304 NewTimeout = SK_RLMT_DEF_TO_VAL;
1305 }
1306
1307 return (NewTimeout);
1308} /* SkRlmtCheckPort */
1309
1310
1311/******************************************************************************
1312 *
1313 * SkRlmtSelectBcRx - select new active port, criteria 1 (CLP)
1314 *
1315 * Description:
1316 * This routine selects the port that received a broadcast frame
1317 * substantially later than all other ports.
1318 *
1319 * Context:
1320 * runtime, pageable?
1321 *
1322 * Returns:
1323 * SK_BOOL
1324 */
1325RLMT_STATIC SK_BOOL SkRlmtSelectBcRx(
1326SK_AC *pAC, /* Adapter Context */
1327SK_IOC IoC, /* I/O Context */
1328SK_U32 Active, /* Active port */
1329SK_U32 PrefPort, /* Preferred port */
1330SK_U32 *pSelect) /* New active port */
1331{
1332 SK_U64 BcTimeStamp;
1333 SK_U32 i;
1334 SK_BOOL PortFound;
1335
1336 BcTimeStamp = 0; /* Not totally necessary, but feeling better. */
1337 PortFound = SK_FALSE;
1338
1339 /* Select port with the latest TimeStamp. */
1340 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1341
1342 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1343 ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
1344 i,
1345 pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
1346 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
1347 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
1348
1349 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
1350 if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
1351 BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
1352 *pSelect = i;
1353 PortFound = SK_TRUE;
1354 }
1355 }
1356 }
1357
1358 if (PortFound) {
1359 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1360 ("Port %d received the last broadcast.\n", *pSelect))
1361
1362 /* Look if another port's time stamp is similar. */
1363 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1364 if (i == *pSelect) {
1365 continue;
1366 }
1367 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
1368 (pAC->Rlmt.Port[i].BcTimeStamp >
1369 BcTimeStamp - SK_RLMT_BC_DELTA ||
1370 pAC->Rlmt.Port[i].BcTimeStamp +
1371 SK_RLMT_BC_DELTA > BcTimeStamp)) {
1372 PortFound = SK_FALSE;
1373
1374 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1375 ("Port %d received a broadcast at a similar time.\n", i))
1376 break;
1377 }
1378 }
1379 }
1380
1381#ifdef DEBUG
1382 if (PortFound) {
1383 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1384 ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
1385 "latest broadcast (%u).\n",
1386 *pSelect,
1387 BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
1388 }
1389#endif /* DEBUG */
1390
1391 return (PortFound);
1392} /* SkRlmtSelectBcRx */
1393
1394
1395/******************************************************************************
1396 *
1397 * SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP)
1398 *
1399 * Description:
1400 * This routine selects a good port (it is PortUp && !SuspectRx).
1401 *
1402 * Context:
1403 * runtime, pageable?
1404 *
1405 * Returns:
1406 * SK_BOOL
1407 */
1408RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect(
1409SK_AC *pAC, /* Adapter Context */
1410SK_IOC IoC, /* I/O Context */
1411SK_U32 Active, /* Active port */
1412SK_U32 PrefPort, /* Preferred port */
1413SK_U32 *pSelect) /* New active port */
1414{
1415 SK_U32 i;
1416 SK_BOOL PortFound;
1417
1418 PortFound = SK_FALSE;
1419
1420 /* Select first port that is PortUp && !SuspectRx. */
1421 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1422 if (!pAC->Rlmt.Port[i].PortDown &&
1423 !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
1424 *pSelect = i;
1425 if (!pAC->Rlmt.Port[Active].PortDown &&
1426 !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
1427 *pSelect = Active;
1428 }
1429 if (!pAC->Rlmt.Port[PrefPort].PortDown &&
1430 !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
1431 *pSelect = PrefPort;
1432 }
1433 PortFound = SK_TRUE;
1434 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1435 ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
1436 *pSelect))
1437 break;
1438 }
1439 }
1440 return (PortFound);
1441} /* SkRlmtSelectNotSuspect */
1442
1443
1444/******************************************************************************
1445 *
1446 * SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP)
1447 *
1448 * Description:
1449 * This routine selects a port that is up.
1450 *
1451 * Context:
1452 * runtime, pageable?
1453 *
1454 * Returns:
1455 * SK_BOOL
1456 */
1457RLMT_STATIC SK_BOOL SkRlmtSelectUp(
1458SK_AC *pAC, /* Adapter Context */
1459SK_IOC IoC, /* I/O Context */
1460SK_U32 Active, /* Active port */
1461SK_U32 PrefPort, /* Preferred port */
1462SK_U32 *pSelect, /* New active port */
1463SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1464{
1465 SK_U32 i;
1466 SK_BOOL PortFound;
1467
1468 PortFound = SK_FALSE;
1469
1470 /* Select first port that is PortUp. */
1471 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1472 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
1473 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1474 *pSelect = i;
1475 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
1476 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1477 *pSelect = Active;
1478 }
1479 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
1480 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1481 *pSelect = PrefPort;
1482 }
1483 PortFound = SK_TRUE;
1484 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1485 ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
1486 break;
1487 }
1488 }
1489 return (PortFound);
1490} /* SkRlmtSelectUp */
1491
1492
1493/******************************************************************************
1494 *
1495 * SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP)
1496 *
1497 * Description:
1498 * This routine selects the port that is going up for the longest time.
1499 *
1500 * Context:
1501 * runtime, pageable?
1502 *
1503 * Returns:
1504 * SK_BOOL
1505 */
1506RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp(
1507SK_AC *pAC, /* Adapter Context */
1508SK_IOC IoC, /* I/O Context */
1509SK_U32 Active, /* Active port */
1510SK_U32 PrefPort, /* Preferred port */
1511SK_U32 *pSelect, /* New active port */
1512SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1513{
1514 SK_U64 GuTimeStamp;
1515 SK_U32 i;
1516 SK_BOOL PortFound;
1517
1518 GuTimeStamp = 0;
1519 PortFound = SK_FALSE;
1520
1521 /* Select port that is PortGoingUp for the longest time. */
1522 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1523 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1524 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1525 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1526 *pSelect = i;
1527 PortFound = SK_TRUE;
1528 break;
1529 }
1530 }
1531
1532 if (!PortFound) {
1533 return (SK_FALSE);
1534 }
1535
1536 for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1537 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1538 pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
1539 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1540 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1541 *pSelect = i;
1542 }
1543 }
1544
1545 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1546 ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
1547 return (SK_TRUE);
1548} /* SkRlmtSelectGoingUp */
1549
1550
1551/******************************************************************************
1552 *
1553 * SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP)
1554 *
1555 * Description:
1556 * This routine selects a port that is down.
1557 *
1558 * Context:
1559 * runtime, pageable?
1560 *
1561 * Returns:
1562 * SK_BOOL
1563 */
1564RLMT_STATIC SK_BOOL SkRlmtSelectDown(
1565SK_AC *pAC, /* Adapter Context */
1566SK_IOC IoC, /* I/O Context */
1567SK_U32 Active, /* Active port */
1568SK_U32 PrefPort, /* Preferred port */
1569SK_U32 *pSelect, /* New active port */
1570SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1571{
1572 SK_U32 i;
1573 SK_BOOL PortFound;
1574
1575 PortFound = SK_FALSE;
1576
1577 /* Select first port that is PortDown. */
1578 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1579 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
1580 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1581 *pSelect = i;
1582 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
1583 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1584 *pSelect = Active;
1585 }
1586 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
1587 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1588 *pSelect = PrefPort;
1589 }
1590 PortFound = SK_TRUE;
1591 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1592 ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
1593 break;
1594 }
1595 }
1596 return (PortFound);
1597} /* SkRlmtSelectDown */
1598
1599
1600/******************************************************************************
1601 *
1602 * SkRlmtCheckSwitch - select new active port and switch to it
1603 *
1604 * Description:
1605 * This routine decides which port should be the active one and queues
1606 * port switching if necessary.
1607 *
1608 * Context:
1609 * runtime, pageable?
1610 *
1611 * Returns:
1612 * Nothing.
1613 */
1614RLMT_STATIC void SkRlmtCheckSwitch(
1615SK_AC *pAC, /* Adapter Context */
1616SK_IOC IoC, /* I/O Context */
1617SK_U32 NetIdx) /* Net index */
1618{
1619 SK_EVPARA Para;
1620 SK_U32 Active;
1621 SK_U32 PrefPort;
1622 SK_U32 i;
1623 SK_BOOL PortFound;
1624
1625 Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */
1626 PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */
1627 PortFound = SK_FALSE;
1628 pAC->Rlmt.CheckSwitch = SK_FALSE;
1629
1630#if 0 /* RW 2001/10/18 - active port becomes always prefered one */
1631 if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */
1632 /* disable auto-fail back */
1633 PrefPort = Active;
1634 }
1635#endif
1636
1637 if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
1638 /* Last link went down - shut down the net. */
1639 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
1640 Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
1641 Para.Para32[1] = NetIdx;
1642 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
1643
1644 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1645 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
1646 Para.Para32[1] = NetIdx;
1647 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
1648 return;
1649 } /* pAC->Rlmt.LinksUp == 0 */
1650 else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
1651 pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
1652 /* First link came up - get the net up. */
1653 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
1654
1655 /*
1656 * If pAC->Rlmt.ActivePort != Para.Para32[0],
1657 * the DRV switches to the port that came up.
1658 */
1659 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
1660 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
1661 if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
1662 i = Active;
1663 }
1664 if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
1665 i = PrefPort;
1666 }
1667 PortFound = SK_TRUE;
1668 break;
1669 }
1670 }
1671
1672 if (PortFound) {
1673 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1674 Para.Para32[1] = NetIdx;
1675 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
1676
1677 pAC->Rlmt.Net[NetIdx].ActivePort = i;
1678 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1679 Para.Para32[1] = NetIdx;
1680 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
1681
1682 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
1683 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
1684 pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
1685 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
1686 CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
1687 /*
1688 * Send announce packet to RLMT multicast address to force
1689 * switches to learn the new location of the logical MAC address.
1690 */
1691 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1692 }
1693 }
1694 else {
1695 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
1696 }
1697
1698 return;
1699 } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
1700 else { /* Cannot be reached in dual-net mode. */
1701 Para.Para32[0] = Active;
1702
1703 /*
1704 * Preselection:
1705 * If RLMT Mode != CheckLinkState
1706 * select port that received a broadcast frame substantially later
1707 * than all other ports
1708 * else select first port that is not SuspectRx
1709 * else select first port that is PortUp
1710 * else select port that is PortGoingUp for the longest time
1711 * else select first port that is PortDown
1712 * else stop.
1713 *
1714 * For the preselected port:
1715 * If ActivePort is equal in quality, select ActivePort.
1716 *
1717 * If PrefPort is equal in quality, select PrefPort.
1718 *
1719 * If ActivePort != SelectedPort,
1720 * If old ActivePort is LinkDown,
1721 * SwitchHard
1722 * else
1723 * SwitchSoft
1724 */
1725 /* check of ChgBcPrio flag added */
1726 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1727 (!pAC->Rlmt.Net[0].ChgBcPrio)) {
1728
1729 if (!PortFound) {
1730 PortFound = SkRlmtSelectBcRx(
1731 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1732 }
1733
1734 if (!PortFound) {
1735 PortFound = SkRlmtSelectNotSuspect(
1736 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1737 }
1738 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1739
1740 /* with changed priority for last broadcast received */
1741 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1742 (pAC->Rlmt.Net[0].ChgBcPrio)) {
1743 if (!PortFound) {
1744 PortFound = SkRlmtSelectNotSuspect(
1745 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1746 }
1747
1748 if (!PortFound) {
1749 PortFound = SkRlmtSelectBcRx(
1750 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1751 }
1752 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1753
1754 if (!PortFound) {
1755 PortFound = SkRlmtSelectUp(
1756 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1757 }
1758
1759 if (!PortFound) {
1760 PortFound = SkRlmtSelectUp(
1761 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1762 }
1763
1764 if (!PortFound) {
1765 PortFound = SkRlmtSelectGoingUp(
1766 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1767 }
1768
1769 if (!PortFound) {
1770 PortFound = SkRlmtSelectGoingUp(
1771 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1772 }
1773
1774 if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
1775 if (!PortFound) {
1776 PortFound = SkRlmtSelectDown(pAC, IoC,
1777 Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1778 }
1779
1780 if (!PortFound) {
1781 PortFound = SkRlmtSelectDown(pAC, IoC,
1782 Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1783 }
1784 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1785
1786 if (PortFound) {
1787
1788 if (Para.Para32[1] != Active) {
1789 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1790 ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
1791 pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
1792 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1793 Port[Para.Para32[0]]->PortNumber;
1794 Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
1795 Port[Para.Para32[1]]->PortNumber;
1796 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
1797 if (pAC->Rlmt.Port[Active].LinkDown) {
1798 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
1799 }
1800 else {
1801 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
1802 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
1803 }
1804 Para.Para32[1] = NetIdx;
1805 Para.Para32[0] =
1806 pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
1807 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
1808 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1809 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
1810 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
1811 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
1812 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
1813 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
1814 &SkRlmtMcAddr)) != NULL) {
1815 /*
1816 * Send announce packet to RLMT multicast address to force
1817 * switches to learn the new location of the logical
1818 * MAC address.
1819 */
1820 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1821 } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
1822 } /* Para.Para32[1] != Active */
1823 } /* PortFound */
1824 else {
1825 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
1826 }
1827 } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
1828 return;
1829} /* SkRlmtCheckSwitch */
1830
1831
1832/******************************************************************************
1833 *
1834 * SkRlmtCheckSeg - Report if segmentation is detected
1835 *
1836 * Description:
1837 * This routine checks if the ports see different root bridges and reports
1838 * segmentation in such a case.
1839 *
1840 * Context:
1841 * runtime, pageable?
1842 *
1843 * Returns:
1844 * Nothing.
1845 */
1846RLMT_STATIC void SkRlmtCheckSeg(
1847SK_AC *pAC, /* Adapter Context */
1848SK_IOC IoC, /* I/O Context */
1849SK_U32 NetIdx) /* Net number */
1850{
1851 SK_EVPARA Para;
1852 SK_RLMT_NET *pNet;
1853 SK_U32 i, j;
1854 SK_BOOL Equal;
1855
1856 pNet = &pAC->Rlmt.Net[NetIdx];
1857 pNet->RootIdSet = SK_FALSE;
1858 Equal = SK_TRUE;
1859
1860 for (i = 0; i < pNet->NumPorts; i++) {
1861 if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
1862 continue;
1863 }
1864
1865 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
1866 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
1867 pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
1868 pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
1869 pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
1870 pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
1871
1872 if (!pNet->RootIdSet) {
1873 pNet->Root = pNet->Port[i]->Root;
1874 pNet->RootIdSet = SK_TRUE;
1875 continue;
1876 }
1877
1878 for (j = 0; j < 8; j ++) {
1879 Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
1880 if (!Equal) {
1881 break;
1882 }
1883 }
1884
1885 if (!Equal) {
1886 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
1887 Para.Para32[0] = NetIdx;
1888 Para.Para32[1] = (SK_U32)-1;
1889 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
1890
1891 pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
1892
1893 /* 2000-03-06 RA: New. */
1894 Para.Para32[0] = NetIdx;
1895 Para.Para32[1] = (SK_U32)-1;
1896 SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
1897 SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
1898 break;
1899 }
1900 } /* for (i = 0; i < pNet->NumPorts; i++) */
1901
1902 /* 2000-03-06 RA: Moved here. */
1903 /* Segmentation check not running anymore. */
1904 pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
1905
1906} /* SkRlmtCheckSeg */
1907
1908
1909/******************************************************************************
1910 *
1911 * SkRlmtPortStart - initialize port variables and start port
1912 *
1913 * Description:
1914 * This routine initializes a port's variables and issues a PORT_START
1915 * to the HWAC module. This handles retries if the start fails or the
1916 * link eventually goes down.
1917 *
1918 * Context:
1919 * runtime, pageable?
1920 *
1921 * Returns:
1922 * Nothing
1923 */
1924RLMT_STATIC void SkRlmtPortStart(
1925SK_AC *pAC, /* Adapter Context */
1926SK_IOC IoC, /* I/O Context */
1927SK_U32 PortNumber) /* Port number */
1928{
1929 SK_EVPARA Para;
1930
1931 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
1932 pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
1933 pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
1934 pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
1935 pAC->Rlmt.Port[PortNumber].CheckingState = 0;
1936 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
1937 Para.Para32[0] = PortNumber;
1938 Para.Para32[1] = (SK_U32)-1;
1939 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
1940} /* SkRlmtPortStart */
1941
1942
1943/******************************************************************************
1944 *
1945 * SkRlmtEvtPortStartTim - PORT_START_TIM
1946 *
1947 * Description:
1948 * This routine handles PORT_START_TIM events.
1949 *
1950 * Context:
1951 * runtime, pageable?
1952 * may be called after SK_INIT_IO
1953 *
1954 * Returns:
1955 * Nothing
1956 */
1957RLMT_STATIC void SkRlmtEvtPortStartTim(
1958SK_AC *pAC, /* Adapter Context */
1959SK_IOC IoC, /* I/O Context */
1960SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
1961{
1962 SK_U32 i;
1963
1964 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1965 ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
1966
1967 if (Para.Para32[1] != (SK_U32)-1) {
1968 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1969 ("Bad Parameter.\n"))
1970 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1971 ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
1972 return;
1973 }
1974
1975 /*
1976 * Used to start non-preferred ports if the preferred one
1977 * does not come up.
1978 * This timeout needs only be set when starting the first
1979 * (preferred) port.
1980 */
1981 if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
1982 /* PORT_START failed. */
1983 for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
1984 if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
1985 SkRlmtPortStart(pAC, IoC,
1986 pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
1987 }
1988 }
1989 }
1990
1991 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1992 ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
1993} /* SkRlmtEvtPortStartTim */
1994
1995
1996/******************************************************************************
1997 *
1998 * SkRlmtEvtLinkUp - LINK_UP
1999 *
2000 * Description:
2001 * This routine handles LLINK_UP events.
2002 *
2003 * Context:
2004 * runtime, pageable?
2005 * may be called after SK_INIT_IO
2006 *
2007 * Returns:
2008 * Nothing
2009 */
2010RLMT_STATIC void SkRlmtEvtLinkUp(
2011SK_AC *pAC, /* Adapter Context */
2012SK_IOC IoC, /* I/O Context */
2013SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
2014{
2015 SK_U32 i;
2016 SK_RLMT_PORT *pRPort;
2017 SK_EVPARA Para2;
2018
2019 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2020 ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
2021
2022 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2023 if (!pRPort->PortStarted) {
2024 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
2025
2026 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2027 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2028 return;
2029 }
2030
2031 if (!pRPort->LinkDown) {
2032 /* RA;:;: Any better solution? */
2033 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2034 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2035 return;
2036 }
2037
2038 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2039 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2040 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2041
2042 /* Do something if timer already fired? */
2043
2044 pRPort->LinkDown = SK_FALSE;
2045 pRPort->PortState = SK_RLMT_PS_GOING_UP;
2046 pRPort->GuTimeStamp = SkOsGetTime(pAC);
2047 pRPort->BcTimeStamp = 0;
2048 pRPort->Net->LinksUp++;
2049 if (pRPort->Net->LinksUp == 1) {
2050 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
2051 }
2052 else {
2053 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
2054 }
2055
2056 for (i = 0; i < pRPort->Net->NumPorts; i++) {
2057 if (!pRPort->Net->Port[i]->PortStarted) {
2058 SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
2059 }
2060 }
2061
2062 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2063
2064 if (pRPort->Net->LinksUp >= 2) {
2065 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
2066 /* Build the check chain. */
2067 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2068 }
2069 }
2070
2071 /* If the first link comes up, start the periodical RLMT timeout. */
2072 if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
2073 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
2074 Para2.Para32[0] = pRPort->Net->NetNumber;
2075 Para2.Para32[1] = (SK_U32)-1;
2076 SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
2077 pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
2078 }
2079
2080 Para2 = Para;
2081 Para2.Para32[1] = (SK_U32)-1;
2082 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
2083 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
2084
2085 /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
2086 if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
2087 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
2088 (Para2.pParaPtr =
2089 SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
2090 &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
2091 ) != NULL) {
2092 /* Send "new" packet to RLMT multicast address. */
2093 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2094 }
2095
2096 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
2097 if ((Para2.pParaPtr =
2098 SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
2099 pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
2100 pRPort->Net->CheckingState |=
2101 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2102
2103 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2104
2105 Para.Para32[1] = (SK_U32)-1;
2106 SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
2107 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2108 }
2109 }
2110
2111 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2112 ("SK_RLMT_LINK_UP Event END.\n"))
2113} /* SkRlmtEvtLinkUp */
2114
2115
2116/******************************************************************************
2117 *
2118 * SkRlmtEvtPortUpTim - PORT_UP_TIM
2119 *
2120 * Description:
2121 * This routine handles PORT_UP_TIM events.
2122 *
2123 * Context:
2124 * runtime, pageable?
2125 * may be called after SK_INIT_IO
2126 *
2127 * Returns:
2128 * Nothing
2129 */
2130RLMT_STATIC void SkRlmtEvtPortUpTim(
2131SK_AC *pAC, /* Adapter Context */
2132SK_IOC IoC, /* I/O Context */
2133SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2134{
2135 SK_RLMT_PORT *pRPort;
2136
2137 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2138 ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
2139
2140 if (Para.Para32[1] != (SK_U32)-1) {
2141 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2142 ("Bad Parameter.\n"))
2143 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2144 ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
2145 return;
2146 }
2147
2148 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2149 if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
2150 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2151 ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
2152 return;
2153 }
2154
2155 pRPort->PortDown = SK_FALSE;
2156 pRPort->PortState = SK_RLMT_PS_UP;
2157 pRPort->Net->PortsUp++;
2158 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2159 if (pAC->Rlmt.NumNets <= 1) {
2160 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2161 }
2162 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
2163 }
2164
2165 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2166 ("SK_RLMT_PORTUP_TIM Event END.\n"))
2167} /* SkRlmtEvtPortUpTim */
2168
2169
2170/******************************************************************************
2171 *
2172 * SkRlmtEvtPortDownTim - PORT_DOWN_*
2173 *
2174 * Description:
2175 * This routine handles PORT_DOWN_* events.
2176 *
2177 * Context:
2178 * runtime, pageable?
2179 * may be called after SK_INIT_IO
2180 *
2181 * Returns:
2182 * Nothing
2183 */
2184RLMT_STATIC void SkRlmtEvtPortDownX(
2185SK_AC *pAC, /* Adapter Context */
2186SK_IOC IoC, /* I/O Context */
2187SK_U32 Event, /* Event code */
2188SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2189{
2190 SK_RLMT_PORT *pRPort;
2191
2192 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2193 ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
2194 Para.Para32[0], Event))
2195
2196 if (Para.Para32[1] != (SK_U32)-1) {
2197 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2198 ("Bad Parameter.\n"))
2199 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2200 ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
2201 return;
2202 }
2203
2204 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2205 if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
2206 !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
2207 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2208 ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
2209 return;
2210 }
2211
2212 /* Stop port's timers. */
2213 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2214 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2215 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2216
2217 if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
2218 pRPort->PortState = SK_RLMT_PS_DOWN;
2219 }
2220
2221 if (!pRPort->PortDown) {
2222 pRPort->Net->PortsUp--;
2223 pRPort->PortDown = SK_TRUE;
2224 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
2225 }
2226
2227 pRPort->PacketsPerTimeSlot = 0;
2228 /* pRPort->DataPacketsPerTimeSlot = 0; */
2229 pRPort->BpduPacketsPerTimeSlot = 0;
2230 pRPort->BcTimeStamp = 0;
2231
2232 /*
2233 * RA;:;: To be checked:
2234 * - actions at RLMT_STOP: We should not switch anymore.
2235 */
2236 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2237 if (Para.Para32[0] ==
2238 pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
2239 /* Active Port went down. */
2240 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2241 }
2242 }
2243
2244 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2245 ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
2246} /* SkRlmtEvtPortDownX */
2247
2248
2249/******************************************************************************
2250 *
2251 * SkRlmtEvtLinkDown - LINK_DOWN
2252 *
2253 * Description:
2254 * This routine handles LINK_DOWN events.
2255 *
2256 * Context:
2257 * runtime, pageable?
2258 * may be called after SK_INIT_IO
2259 *
2260 * Returns:
2261 * Nothing
2262 */
2263RLMT_STATIC void SkRlmtEvtLinkDown(
2264SK_AC *pAC, /* Adapter Context */
2265SK_IOC IoC, /* I/O Context */
2266SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
2267{
2268 SK_RLMT_PORT *pRPort;
2269
2270 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2271 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2272 ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
2273
2274 if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
2275 pRPort->Net->LinksUp--;
2276 pRPort->LinkDown = SK_TRUE;
2277 pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
2278 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
2279
2280 if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
2281 /* Build the check chain. */
2282 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2283 }
2284
2285 /* Ensure that port is marked down. */
2286 Para.Para32[1] = -1;
2287 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
2288 }
2289
2290 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2291 ("SK_RLMT_LINK_DOWN Event END.\n"))
2292} /* SkRlmtEvtLinkDown */
2293
2294
2295/******************************************************************************
2296 *
2297 * SkRlmtEvtPortAddr - PORT_ADDR
2298 *
2299 * Description:
2300 * This routine handles PORT_ADDR events.
2301 *
2302 * Context:
2303 * runtime, pageable?
2304 * may be called after SK_INIT_IO
2305 *
2306 * Returns:
2307 * Nothing
2308 */
2309RLMT_STATIC void SkRlmtEvtPortAddr(
2310SK_AC *pAC, /* Adapter Context */
2311SK_IOC IoC, /* I/O Context */
2312SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2313{
2314 SK_U32 i, j;
2315 SK_RLMT_PORT *pRPort;
2316 SK_MAC_ADDR *pOldMacAddr;
2317 SK_MAC_ADDR *pNewMacAddr;
2318
2319 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2320 ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
2321
2322 if (Para.Para32[1] != (SK_U32)-1) {
2323 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2324 ("Bad Parameter.\n"))
2325 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2326 ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
2327 return;
2328 }
2329
2330 /* Port's physical MAC address changed. */
2331 pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
2332 pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
2333
2334 /*
2335 * NOTE: This is not scalable for solutions where ports are
2336 * checked remotely. There, we need to send an RLMT
2337 * address change packet - and how do we ensure delivery?
2338 */
2339 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
2340 pRPort = &pAC->Rlmt.Port[i];
2341 for (j = 0; j < pRPort->PortsChecked; j++) {
2342 if (SK_ADDR_EQUAL(
2343 pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
2344 pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
2345 }
2346 }
2347 }
2348
2349 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2350 ("SK_RLMT_PORT_ADDR Event END.\n"))
2351} /* SkRlmtEvtPortAddr */
2352
2353
2354/******************************************************************************
2355 *
2356 * SkRlmtEvtStart - START
2357 *
2358 * Description:
2359 * This routine handles START events.
2360 *
2361 * Context:
2362 * runtime, pageable?
2363 * may be called after SK_INIT_IO
2364 *
2365 * Returns:
2366 * Nothing
2367 */
2368RLMT_STATIC void SkRlmtEvtStart(
2369SK_AC *pAC, /* Adapter Context */
2370SK_IOC IoC, /* I/O Context */
2371SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2372{
2373 SK_EVPARA Para2;
2374 SK_U32 PortIdx;
2375 SK_U32 PortNumber;
2376
2377 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2378 ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
2379
2380 if (Para.Para32[1] != (SK_U32)-1) {
2381 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2382 ("Bad Parameter.\n"))
2383 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2384 ("SK_RLMT_START Event EMPTY.\n"))
2385 return;
2386 }
2387
2388 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2389 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2390 ("Bad NetNumber %d.\n", Para.Para32[0]))
2391 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2392 ("SK_RLMT_START Event EMPTY.\n"))
2393 return;
2394 }
2395
2396 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
2397 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2398 ("SK_RLMT_START Event EMPTY.\n"))
2399 return;
2400 }
2401
2402 if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
2403 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2404 ("All nets should have been started.\n"))
2405 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2406 ("SK_RLMT_START Event EMPTY.\n"))
2407 return;
2408 }
2409
2410 if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
2411 pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
2412 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
2413
2414 /* Change PrefPort to internal default. */
2415 Para2.Para32[0] = 0xFFFFFFFF;
2416 Para2.Para32[1] = Para.Para32[0];
2417 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
2418 }
2419
2420 PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
2421 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
2422
2423 pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
2424 pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
2425 pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
2426 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
2427
2428 /* Start preferred port. */
2429 SkRlmtPortStart(pAC, IoC, PortNumber);
2430
2431 /* Start Timer (for first port only). */
2432 Para2.Para32[0] = PortNumber;
2433 Para2.Para32[1] = (SK_U32)-1;
2434 SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
2435 SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
2436
2437 pAC->Rlmt.NetsStarted++;
2438
2439 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2440 ("SK_RLMT_START Event END.\n"))
2441} /* SkRlmtEvtStart */
2442
2443
2444/******************************************************************************
2445 *
2446 * SkRlmtEvtStop - STOP
2447 *
2448 * Description:
2449 * This routine handles STOP events.
2450 *
2451 * Context:
2452 * runtime, pageable?
2453 * may be called after SK_INIT_IO
2454 *
2455 * Returns:
2456 * Nothing
2457 */
2458RLMT_STATIC void SkRlmtEvtStop(
2459SK_AC *pAC, /* Adapter Context */
2460SK_IOC IoC, /* I/O Context */
2461SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2462{
2463 SK_EVPARA Para2;
2464 SK_U32 PortNumber;
2465 SK_U32 i;
2466
2467 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2468 ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
2469
2470 if (Para.Para32[1] != (SK_U32)-1) {
2471 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2472 ("Bad Parameter.\n"))
2473 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2474 ("SK_RLMT_STOP Event EMPTY.\n"))
2475 return;
2476 }
2477
2478 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2479 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2480 ("Bad NetNumber %d.\n", Para.Para32[0]))
2481 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2482 ("SK_RLMT_STOP Event EMPTY.\n"))
2483 return;
2484 }
2485
2486 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
2487 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2488 ("SK_RLMT_STOP Event EMPTY.\n"))
2489 return;
2490 }
2491
2492 if (pAC->Rlmt.NetsStarted == 0) {
2493 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2494 ("All nets are stopped.\n"))
2495 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2496 ("SK_RLMT_STOP Event EMPTY.\n"))
2497 return;
2498 }
2499
2500 /* Stop RLMT timers. */
2501 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
2502 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
2503
2504 /* Stop net. */
2505 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
2506 pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
2507 Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
2508 Para2.Para32[1] = Para.Para32[0]; /* Net# */
2509 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
2510
2511 /* Stop ports. */
2512 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2513 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2514 if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
2515 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
2516 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
2517 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
2518
2519 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
2520 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
2521 pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
2522 Para2.Para32[0] = PortNumber;
2523 Para2.Para32[1] = (SK_U32)-1;
2524 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
2525 }
2526 }
2527
2528 pAC->Rlmt.NetsStarted--;
2529
2530 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2531 ("SK_RLMT_STOP Event END.\n"))
2532} /* SkRlmtEvtStop */
2533
2534
2535/******************************************************************************
2536 *
2537 * SkRlmtEvtTim - TIM
2538 *
2539 * Description:
2540 * This routine handles TIM events.
2541 *
2542 * Context:
2543 * runtime, pageable?
2544 * may be called after SK_INIT_IO
2545 *
2546 * Returns:
2547 * Nothing
2548 */
2549RLMT_STATIC void SkRlmtEvtTim(
2550SK_AC *pAC, /* Adapter Context */
2551SK_IOC IoC, /* I/O Context */
2552SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2553{
2554 SK_RLMT_PORT *pRPort;
2555 SK_U32 Timeout;
2556 SK_U32 NewTimeout;
2557 SK_U32 PortNumber;
2558 SK_U32 i;
2559
2560 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2561 ("SK_RLMT_TIM Event BEGIN.\n"))
2562
2563 if (Para.Para32[1] != (SK_U32)-1) {
2564 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2565 ("Bad Parameter.\n"))
2566 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2567 ("SK_RLMT_TIM Event EMPTY.\n"))
2568 return;
2569 }
2570
2571 if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
2572 pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
2573 /* Mode changed or all links down: No more link checking. */
2574 return;
2575 }
2576
2577#if 0
2578 pAC->Rlmt.SwitchCheckCounter--;
2579 if (pAC->Rlmt.SwitchCheckCounter == 0) {
2580 pAC->Rlmt.SwitchCheckCounter;
2581 }
2582#endif /* 0 */
2583
2584 NewTimeout = SK_RLMT_DEF_TO_VAL;
2585 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2586 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2587 pRPort = &pAC->Rlmt.Port[PortNumber];
2588 if (!pRPort->LinkDown) {
2589 Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
2590 if (Timeout < NewTimeout) {
2591 NewTimeout = Timeout;
2592 }
2593
2594 /*
2595 * These counters should be set to 0 for all ports before the
2596 * first frame is sent in the next loop.
2597 */
2598 pRPort->PacketsPerTimeSlot = 0;
2599 /* pRPort->DataPacketsPerTimeSlot = 0; */
2600 pRPort->BpduPacketsPerTimeSlot = 0;
2601 }
2602 }
2603 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
2604
2605 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
2606 /*
2607 * If checking remote ports, also send packets if
2608 * (LinksUp == 1) &&
2609 * this port checks at least one (remote) port.
2610 */
2611
2612 /*
2613 * Must be new loop, as SkRlmtCheckPort can request to
2614 * check segmentation when e.g. checking the last port.
2615 */
2616 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2617 if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
2618 SkRlmtSend(pAC, IoC,
2619 pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
2620 }
2621 }
2622 }
2623
2624 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
2625 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
2626 Para);
2627
2628 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
2629 (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
2630 (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
2631 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
2632 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2633 pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
2634 pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
2635 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2636 }
2637
2638 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2639 ("SK_RLMT_TIM Event END.\n"))
2640} /* SkRlmtEvtTim */
2641
2642
2643/******************************************************************************
2644 *
2645 * SkRlmtEvtSegTim - SEG_TIM
2646 *
2647 * Description:
2648 * This routine handles SEG_TIM events.
2649 *
2650 * Context:
2651 * runtime, pageable?
2652 * may be called after SK_INIT_IO
2653 *
2654 * Returns:
2655 * Nothing
2656 */
2657RLMT_STATIC void SkRlmtEvtSegTim(
2658SK_AC *pAC, /* Adapter Context */
2659SK_IOC IoC, /* I/O Context */
2660SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2661{
2662#ifdef xDEBUG
2663 int j;
2664#endif /* DEBUG */
2665
2666 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2667 ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
2668
2669 if (Para.Para32[1] != (SK_U32)-1) {
2670 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2671 ("Bad Parameter.\n"))
2672 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2673 ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
2674 return;
2675 }
2676
2677#ifdef xDEBUG
2678 for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
2679 SK_ADDR_PORT *pAPort;
2680 SK_U32 k;
2681 SK_U16 *InAddr;
2682 SK_U8 InAddr8[6];
2683
2684 InAddr = (SK_U16 *)&InAddr8[0];
2685 pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
2686 for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
2687 /* Get exact match address k from port j. */
2688 XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2689 XM_EXM(k), InAddr);
2690 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2691 ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n",
2692 k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2693 InAddr8[0], InAddr8[1], InAddr8[2],
2694 InAddr8[3], InAddr8[4], InAddr8[5],
2695 pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
2696 pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
2697 pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
2698 }
2699 }
2700#endif /* xDEBUG */
2701
2702 SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
2703
2704 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2705 ("SK_RLMT_SEG_TIM Event END.\n"))
2706} /* SkRlmtEvtSegTim */
2707
2708
2709/******************************************************************************
2710 *
2711 * SkRlmtEvtPacketRx - PACKET_RECEIVED
2712 *
2713 * Description:
2714 * This routine handles PACKET_RECEIVED events.
2715 *
2716 * Context:
2717 * runtime, pageable?
2718 * may be called after SK_INIT_IO
2719 *
2720 * Returns:
2721 * Nothing
2722 */
2723RLMT_STATIC void SkRlmtEvtPacketRx(
2724SK_AC *pAC, /* Adapter Context */
2725SK_IOC IoC, /* I/O Context */
2726SK_EVPARA Para) /* SK_MBUF *pMb */
2727{
2728 SK_MBUF *pMb;
2729 SK_MBUF *pNextMb;
2730 SK_U32 NetNumber;
2731
2732
2733 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2734 ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
2735
2736 /* Should we ignore frames during port switching? */
2737
2738#ifdef DEBUG
2739 pMb = Para.pParaPtr;
2740 if (pMb == NULL) {
2741 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
2742 }
2743 else if (pMb->pNext != NULL) {
2744 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2745 ("More than one mbuf or pMb->pNext not set.\n"))
2746 }
2747#endif /* DEBUG */
2748
2749 for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
2750 pNextMb = pMb->pNext;
2751 pMb->pNext = NULL;
2752
2753 NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
2754 if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
2755 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
2756 }
2757 else {
2758 SkRlmtPacketReceive(pAC, IoC, pMb);
2759 }
2760 }
2761
2762 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2763 ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
2764} /* SkRlmtEvtPacketRx */
2765
2766
2767/******************************************************************************
2768 *
2769 * SkRlmtEvtStatsClear - STATS_CLEAR
2770 *
2771 * Description:
2772 * This routine handles STATS_CLEAR events.
2773 *
2774 * Context:
2775 * runtime, pageable?
2776 * may be called after SK_INIT_IO
2777 *
2778 * Returns:
2779 * Nothing
2780 */
2781RLMT_STATIC void SkRlmtEvtStatsClear(
2782SK_AC *pAC, /* Adapter Context */
2783SK_IOC IoC, /* I/O Context */
2784SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2785{
2786 SK_U32 i;
2787 SK_RLMT_PORT *pRPort;
2788
2789 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2790 ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
2791
2792 if (Para.Para32[1] != (SK_U32)-1) {
2793 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2794 ("Bad Parameter.\n"))
2795 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2796 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
2797 return;
2798 }
2799
2800 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2801 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2802 ("Bad NetNumber %d.\n", Para.Para32[0]))
2803 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2804 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
2805 return;
2806 }
2807
2808 /* Clear statistics for logical and physical ports. */
2809 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2810 pRPort =
2811 &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
2812 pRPort->TxHelloCts = 0;
2813 pRPort->RxHelloCts = 0;
2814 pRPort->TxSpHelloReqCts = 0;
2815 pRPort->RxSpHelloCts = 0;
2816 }
2817
2818 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2819 ("SK_RLMT_STATS_CLEAR Event END.\n"))
2820} /* SkRlmtEvtStatsClear */
2821
2822
2823/******************************************************************************
2824 *
2825 * SkRlmtEvtStatsUpdate - STATS_UPDATE
2826 *
2827 * Description:
2828 * This routine handles STATS_UPDATE events.
2829 *
2830 * Context:
2831 * runtime, pageable?
2832 * may be called after SK_INIT_IO
2833 *
2834 * Returns:
2835 * Nothing
2836 */
2837RLMT_STATIC void SkRlmtEvtStatsUpdate(
2838SK_AC *pAC, /* Adapter Context */
2839SK_IOC IoC, /* I/O Context */
2840SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2841{
2842 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2843 ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
2844
2845 if (Para.Para32[1] != (SK_U32)-1) {
2846 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2847 ("Bad Parameter.\n"))
2848 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2849 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
2850 return;
2851 }
2852
2853 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2854 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2855 ("Bad NetNumber %d.\n", Para.Para32[0]))
2856 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2857 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
2858 return;
2859 }
2860
2861 /* Update statistics - currently always up-to-date. */
2862
2863 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2864 ("SK_RLMT_STATS_UPDATE Event END.\n"))
2865} /* SkRlmtEvtStatsUpdate */
2866
2867
2868/******************************************************************************
2869 *
2870 * SkRlmtEvtPrefportChange - PREFPORT_CHANGE
2871 *
2872 * Description:
2873 * This routine handles PREFPORT_CHANGE events.
2874 *
2875 * Context:
2876 * runtime, pageable?
2877 * may be called after SK_INIT_IO
2878 *
2879 * Returns:
2880 * Nothing
2881 */
2882RLMT_STATIC void SkRlmtEvtPrefportChange(
2883SK_AC *pAC, /* Adapter Context */
2884SK_IOC IoC, /* I/O Context */
2885SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */
2886{
2887 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2888 ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
2889
2890 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
2891 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2892 ("Bad NetNumber %d.\n", Para.Para32[1]))
2893 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2894 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
2895 return;
2896 }
2897
2898 /* 0xFFFFFFFF == auto-mode. */
2899 if (Para.Para32[0] == 0xFFFFFFFF) {
2900 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
2901 }
2902 else {
2903 if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
2904 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
2905
2906 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2907 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
2908 return;
2909 }
2910
2911 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
2912 }
2913
2914 pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
2915
2916 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
2917 SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
2918 }
2919
2920 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2921 ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
2922} /* SkRlmtEvtPrefportChange */
2923
2924
2925/******************************************************************************
2926 *
2927 * SkRlmtEvtSetNets - SET_NETS
2928 *
2929 * Description:
2930 * This routine handles SET_NETS events.
2931 *
2932 * Context:
2933 * runtime, pageable?
2934 * may be called after SK_INIT_IO
2935 *
2936 * Returns:
2937 * Nothing
2938 */
2939RLMT_STATIC void SkRlmtEvtSetNets(
2940SK_AC *pAC, /* Adapter Context */
2941SK_IOC IoC, /* I/O Context */
2942SK_EVPARA Para) /* SK_U32 NumNets; SK_U32 -1 */
2943{
2944 int i;
2945
2946 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2947 ("SK_RLMT_SET_NETS Event BEGIN.\n"))
2948
2949 if (Para.Para32[1] != (SK_U32)-1) {
2950 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2951 ("Bad Parameter.\n"))
2952 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2953 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2954 return;
2955 }
2956
2957 if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
2958 Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
2959 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2960 ("Bad number of nets: %d.\n", Para.Para32[0]))
2961 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2962 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2963 return;
2964 }
2965
2966 if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */
2967 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2968 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2969 return;
2970 }
2971
2972 /* Entering and leaving dual mode only allowed while nets are stopped. */
2973 if (pAC->Rlmt.NetsStarted > 0) {
2974 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2975 ("Changing dual mode only allowed while all nets are stopped.\n"))
2976 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2977 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2978 return;
2979 }
2980
2981 if (Para.Para32[0] == 1) {
2982 if (pAC->Rlmt.NumNets > 1) {
2983 /* Clear logical MAC addr from second net's active port. */
2984 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
2985 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
2986 pAC->Rlmt.Net[1].NumPorts = 0;
2987 }
2988
2989 pAC->Rlmt.NumNets = Para.Para32[0];
2990 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
2991 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
2992 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
2993 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
2994 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
2995 /* Just assuming. */
2996 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
2997 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
2998 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
2999 pAC->Rlmt.Net[i].NetNumber = i;
3000 }
3001
3002 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
3003 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
3004
3005 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3006
3007 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3008 ("RLMT: Changed to one net with two ports.\n"))
3009 }
3010 else if (Para.Para32[0] == 2) {
3011 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
3012 pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
3013 pAC->Rlmt.Net[0].NumPorts =
3014 pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
3015
3016 pAC->Rlmt.NumNets = Para.Para32[0];
3017 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
3018 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
3019 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
3020 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
3021 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
3022 /* Just assuming. */
3023 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
3024 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
3025 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
3026
3027 pAC->Rlmt.Net[i].NetNumber = i;
3028 }
3029
3030 /* Set logical MAC addr on second net's active port. */
3031 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
3032 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
3033
3034 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3035
3036 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3037 ("RLMT: Changed to two nets with one port each.\n"))
3038 }
3039 else {
3040 /* Not implemented for more than two nets. */
3041 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3042 ("SetNets not implemented for more than two nets.\n"))
3043 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3044 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3045 return;
3046 }
3047
3048 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3049 ("SK_RLMT_SET_NETS Event END.\n"))
3050} /* SkRlmtSetNets */
3051
3052
3053/******************************************************************************
3054 *
3055 * SkRlmtEvtModeChange - MODE_CHANGE
3056 *
3057 * Description:
3058 * This routine handles MODE_CHANGE events.
3059 *
3060 * Context:
3061 * runtime, pageable?
3062 * may be called after SK_INIT_IO
3063 *
3064 * Returns:
3065 * Nothing
3066 */
3067RLMT_STATIC void SkRlmtEvtModeChange(
3068SK_AC *pAC, /* Adapter Context */
3069SK_IOC IoC, /* I/O Context */
3070SK_EVPARA Para) /* SK_U32 NewMode; SK_U32 NetNumber */
3071{
3072 SK_EVPARA Para2;
3073 SK_U32 i;
3074 SK_U32 PrevRlmtMode;
3075
3076 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3077 ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
3078
3079 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
3080 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3081 ("Bad NetNumber %d.\n", Para.Para32[1]))
3082 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3083 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3084 return;
3085 }
3086
3087 Para.Para32[0] |= SK_RLMT_CHECK_LINK;
3088
3089 if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
3090 Para.Para32[0] != SK_RLMT_MODE_CLS) {
3091 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
3092 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3093 ("Forced RLMT mode to CLS on single port net.\n"))
3094 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3095 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3096 return;
3097 }
3098
3099 /* Update RLMT mode. */
3100 PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
3101 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
3102
3103 if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
3104 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
3105 /* SK_RLMT_CHECK_LOC_LINK bit changed. */
3106 if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
3107 pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
3108 pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
3109 /* 20001207 RA: Was "PortsUp == 1". */
3110 Para2.Para32[0] = Para.Para32[1];
3111 Para2.Para32[1] = (SK_U32)-1;
3112 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
3113 pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
3114 SKGE_RLMT, SK_RLMT_TIM, Para2);
3115 }
3116 }
3117
3118 if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
3119 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
3120 /* SK_RLMT_CHECK_SEG bit changed. */
3121 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
3122 (void)SkAddrMcClear(pAC, IoC,
3123 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3124 SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
3125
3126 /* Add RLMT MC address. */
3127 (void)SkAddrMcAdd(pAC, IoC,
3128 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3129 &SkRlmtMcAddr, SK_ADDR_PERMANENT);
3130
3131 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
3132 SK_RLMT_CHECK_SEG) != 0) {
3133 /* Add BPDU MC address. */
3134 (void)SkAddrMcAdd(pAC, IoC,
3135 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3136 &BridgeMcAddr, SK_ADDR_PERMANENT);
3137
3138 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
3139 if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
3140 (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
3141 pAC, IoC, i)) != NULL) {
3142 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
3143 SK_FALSE;
3144 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
3145 }
3146 }
3147 }
3148 (void)SkAddrMcUpdate(pAC, IoC,
3149 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
3150 } /* for ... */
3151
3152 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
3153 Para2.Para32[0] = Para.Para32[1];
3154 Para2.Para32[1] = (SK_U32)-1;
3155 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
3156 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
3157 }
3158 } /* SK_RLMT_CHECK_SEG bit changed. */
3159
3160 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3161 ("SK_RLMT_MODE_CHANGE Event END.\n"))
3162} /* SkRlmtEvtModeChange */
3163
3164
3165/******************************************************************************
3166 *
3167 * SkRlmtEvent - a PORT- or an RLMT-specific event happened
3168 *
3169 * Description:
3170 * This routine calls subroutines to handle PORT- and RLMT-specific events.
3171 *
3172 * Context:
3173 * runtime, pageable?
3174 * may be called after SK_INIT_IO
3175 *
3176 * Returns:
3177 * 0
3178 */
3179int SkRlmtEvent(
3180SK_AC *pAC, /* Adapter Context */
3181SK_IOC IoC, /* I/O Context */
3182SK_U32 Event, /* Event code */
3183SK_EVPARA Para) /* Event-specific parameter */
3184{
3185 switch (Event) {
3186
3187 /* ----- PORT events ----- */
3188
3189 case SK_RLMT_PORTSTART_TIM: /* From RLMT via TIME. */
3190 SkRlmtEvtPortStartTim(pAC, IoC, Para);
3191 break;
3192 case SK_RLMT_LINK_UP: /* From SIRQ. */
3193 SkRlmtEvtLinkUp(pAC, IoC, Para);
3194 break;
3195 case SK_RLMT_PORTUP_TIM: /* From RLMT via TIME. */
3196 SkRlmtEvtPortUpTim(pAC, IoC, Para);
3197 break;
3198 case SK_RLMT_PORTDOWN: /* From RLMT. */
3199 case SK_RLMT_PORTDOWN_RX_TIM: /* From RLMT via TIME. */
3200 case SK_RLMT_PORTDOWN_TX_TIM: /* From RLMT via TIME. */
3201 SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
3202 break;
3203 case SK_RLMT_LINK_DOWN: /* From SIRQ. */
3204 SkRlmtEvtLinkDown(pAC, IoC, Para);
3205 break;
3206 case SK_RLMT_PORT_ADDR: /* From ADDR. */
3207 SkRlmtEvtPortAddr(pAC, IoC, Para);
3208 break;
3209
3210 /* ----- RLMT events ----- */
3211
3212 case SK_RLMT_START: /* From DRV. */
3213 SkRlmtEvtStart(pAC, IoC, Para);
3214 break;
3215 case SK_RLMT_STOP: /* From DRV. */
3216 SkRlmtEvtStop(pAC, IoC, Para);
3217 break;
3218 case SK_RLMT_TIM: /* From RLMT via TIME. */
3219 SkRlmtEvtTim(pAC, IoC, Para);
3220 break;
3221 case SK_RLMT_SEG_TIM:
3222 SkRlmtEvtSegTim(pAC, IoC, Para);
3223 break;
3224 case SK_RLMT_PACKET_RECEIVED: /* From DRV. */
3225 SkRlmtEvtPacketRx(pAC, IoC, Para);
3226 break;
3227 case SK_RLMT_STATS_CLEAR: /* From PNMI. */
3228 SkRlmtEvtStatsClear(pAC, IoC, Para);
3229 break;
3230 case SK_RLMT_STATS_UPDATE: /* From PNMI. */
3231 SkRlmtEvtStatsUpdate(pAC, IoC, Para);
3232 break;
3233 case SK_RLMT_PREFPORT_CHANGE: /* From PNMI. */
3234 SkRlmtEvtPrefportChange(pAC, IoC, Para);
3235 break;
3236 case SK_RLMT_MODE_CHANGE: /* From PNMI. */
3237 SkRlmtEvtModeChange(pAC, IoC, Para);
3238 break;
3239 case SK_RLMT_SET_NETS: /* From DRV. */
3240 SkRlmtEvtSetNets(pAC, IoC, Para);
3241 break;
3242
3243 /* ----- Unknown events ----- */
3244
3245 default: /* Create error log entry. */
3246 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3247 ("Unknown RLMT Event %d.\n", Event))
3248 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
3249 break;
3250 } /* switch() */
3251
3252 return (0);
3253} /* SkRlmtEvent */
3254
3255#ifdef __cplusplus
3256}
3257#endif /* __cplusplus */
diff --git a/drivers/net/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c
deleted file mode 100644
index 4e462955ecd8..000000000000
--- a/drivers/net/sk98lin/sktimer.c
+++ /dev/null
@@ -1,250 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sktimer.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.14 $
6 * Date: $Date: 2003/09/16 13:46:51 $
7 * Purpose: High level timer functions.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26/*
27 * Event queue and dispatcher
28 */
29#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
30static const char SysKonnectFileId[] =
31 "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
32#endif
33
34#include "h/skdrv1st.h" /* Driver Specific Definitions */
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#ifdef __C2MAN__
38/*
39 Event queue management.
40
41 General Description:
42
43 */
44intro()
45{}
46#endif
47
48
49/* Forward declaration */
50static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
51
52
53/*
54 * Inits the software timer
55 *
56 * needs to be called during Init level 1.
57 */
58void SkTimerInit(
59SK_AC *pAC, /* Adapters context */
60SK_IOC Ioc, /* IoContext */
61int Level) /* Init Level */
62{
63 switch (Level) {
64 case SK_INIT_DATA:
65 pAC->Tim.StQueue = NULL;
66 break;
67 case SK_INIT_IO:
68 SkHwtInit(pAC, Ioc);
69 SkTimerDone(pAC, Ioc);
70 break;
71 default:
72 break;
73 }
74}
75
76/*
77 * Stops a high level timer
78 * - If a timer is not in the queue the function returns normally, too.
79 */
80void SkTimerStop(
81SK_AC *pAC, /* Adapters context */
82SK_IOC Ioc, /* IoContext */
83SK_TIMER *pTimer) /* Timer Pointer to be started */
84{
85 SK_TIMER **ppTimPrev;
86 SK_TIMER *pTm;
87
88 /*
89 * remove timer from queue
90 */
91 pTimer->TmActive = SK_FALSE;
92
93 if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
94 SkHwtStop(pAC, Ioc);
95 }
96
97 for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
98 ppTimPrev = &pTm->TmNext ) {
99
100 if (pTm == pTimer) {
101 /*
102 * Timer found in queue
103 * - dequeue it and
104 * - correct delta of the next timer
105 */
106 *ppTimPrev = pTm->TmNext;
107
108 if (pTm->TmNext) {
109 /* correct delta of next timer in queue */
110 pTm->TmNext->TmDelta += pTm->TmDelta;
111 }
112 return;
113 }
114 }
115}
116
117/*
118 * Start a high level software timer
119 */
120void SkTimerStart(
121SK_AC *pAC, /* Adapters context */
122SK_IOC Ioc, /* IoContext */
123SK_TIMER *pTimer, /* Timer Pointer to be started */
124SK_U32 Time, /* Time value */
125SK_U32 Class, /* Event Class for this timer */
126SK_U32 Event, /* Event Value for this timer */
127SK_EVPARA Para) /* Event Parameter for this timer */
128{
129 SK_TIMER **ppTimPrev;
130 SK_TIMER *pTm;
131 SK_U32 Delta;
132
133 Time /= 16; /* input is uS, clock ticks are 16uS */
134
135 if (!Time)
136 Time = 1;
137
138 SkTimerStop(pAC, Ioc, pTimer);
139
140 pTimer->TmClass = Class;
141 pTimer->TmEvent = Event;
142 pTimer->TmPara = Para;
143 pTimer->TmActive = SK_TRUE;
144
145 if (!pAC->Tim.StQueue) {
146 /* First Timer to be started */
147 pAC->Tim.StQueue = pTimer;
148 pTimer->TmNext = NULL;
149 pTimer->TmDelta = Time;
150
151 SkHwtStart(pAC, Ioc, Time);
152
153 return;
154 }
155
156 /*
157 * timer correction
158 */
159 timer_done(pAC, Ioc, 0);
160
161 /*
162 * find position in queue
163 */
164 Delta = 0;
165 for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
166 ppTimPrev = &pTm->TmNext ) {
167
168 if (Delta + pTm->TmDelta > Time) {
169 /* Position found */
170 /* Here the timer needs to be inserted. */
171 break;
172 }
173 Delta += pTm->TmDelta;
174 }
175
176 /* insert in queue */
177 *ppTimPrev = pTimer;
178 pTimer->TmNext = pTm;
179 pTimer->TmDelta = Time - Delta;
180
181 if (pTm) {
182 /* There is a next timer
183 * -> correct its Delta value.
184 */
185 pTm->TmDelta -= pTimer->TmDelta;
186 }
187
188 /* restart with first */
189 SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
190}
191
192
193void SkTimerDone(
194SK_AC *pAC, /* Adapters context */
195SK_IOC Ioc) /* IoContext */
196{
197 timer_done(pAC, Ioc, 1);
198}
199
200
201static void timer_done(
202SK_AC *pAC, /* Adapters context */
203SK_IOC Ioc, /* IoContext */
204int Restart) /* Do we need to restart the Hardware timer ? */
205{
206 SK_U32 Delta;
207 SK_TIMER *pTm;
208 SK_TIMER *pTComp; /* Timer completed now now */
209 SK_TIMER **ppLast; /* Next field of Last timer to be deq */
210 int Done = 0;
211
212 Delta = SkHwtRead(pAC, Ioc);
213
214 ppLast = &pAC->Tim.StQueue;
215 pTm = pAC->Tim.StQueue;
216 while (pTm && !Done) {
217 if (Delta >= pTm->TmDelta) {
218 /* Timer ran out */
219 pTm->TmActive = SK_FALSE;
220 Delta -= pTm->TmDelta;
221 ppLast = &pTm->TmNext;
222 pTm = pTm->TmNext;
223 }
224 else {
225 /* We found the first timer that did not run out */
226 pTm->TmDelta -= Delta;
227 Delta = 0;
228 Done = 1;
229 }
230 }
231 *ppLast = NULL;
232 /*
233 * pTm points to the first Timer that did not run out.
234 * StQueue points to the first Timer that run out.
235 */
236
237 for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
238 SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
239 }
240
241 /* Set head of timer queue to the first timer that did not run out */
242 pAC->Tim.StQueue = pTm;
243
244 if (Restart && pAC->Tim.StQueue) {
245 /* Restart HW timer */
246 SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
247 }
248}
249
250/* End of file */
diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
deleted file mode 100644
index 1e662aaebf84..000000000000
--- a/drivers/net/sk98lin/skvpd.c
+++ /dev/null
@@ -1,1091 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skvpd.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.37 $
6 * Date: $Date: 2003/01/13 10:42:45 $
7 * Purpose: Shared software to read and write VPD data
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/*
25 Please refer skvpd.txt for information how to include this module
26 */
27static const char SysKonnectFileId[] =
28 "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
29
30#include "h/skdrv1st.h"
31#include "h/sktypes.h"
32#include "h/skdebug.h"
33#include "h/skdrv2nd.h"
34
35/*
36 * Static functions
37 */
38#ifndef SK_KR_PROTO
39static SK_VPD_PARA *vpd_find_para(
40 SK_AC *pAC,
41 const char *key,
42 SK_VPD_PARA *p);
43#else /* SK_KR_PROTO */
44static SK_VPD_PARA *vpd_find_para();
45#endif /* SK_KR_PROTO */
46
47/*
48 * waits for a completion of a VPD transfer
49 * The VPD transfer must complete within SK_TICKS_PER_SEC/16
50 *
51 * returns 0: success, transfer completes
52 * error exit(9) with a error message
53 */
54static int VpdWait(
55SK_AC *pAC, /* Adapters context */
56SK_IOC IoC, /* IO Context */
57int event) /* event to wait for (VPD_READ / VPD_write) completion*/
58{
59 SK_U64 start_time;
60 SK_U16 state;
61
62 SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
63 ("VPD wait for %s\n", event?"Write":"Read"));
64 start_time = SkOsGetTime(pAC);
65 do {
66 if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
67
68 /* Bug fix AF: Thu Mar 28 2002
69 * Do not call: VPD_STOP(pAC, IoC);
70 * A pending VPD read cycle can not be aborted by writing
71 * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
72 * Although the write threshold in the OUR-register protects
73 * VPD read only space from being overwritten this does not
74 * protect a VPD read from being `converted` into a VPD write
75 * operation (on the fly). As a consequence the VPD_STOP would
76 * delete VPD read only data. In case of any problems with the
77 * I2C bus we exit the loop here. The I2C read operation can
78 * not be aborted except by a reset (->LR).
79 */
80 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
81 ("ERROR:VPD wait timeout\n"));
82 return(1);
83 }
84
85 VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
86
87 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
88 ("state = %x, event %x\n",state,event));
89 } while((int)(state & PCI_VPD_FLAG) == event);
90
91 return(0);
92}
93
94#ifdef SKDIAG
95
96/*
97 * Read the dword at address 'addr' from the VPD EEPROM.
98 *
99 * Needed Time: MIN 1,3 ms MAX 2,6 ms
100 *
101 * Note: The DWord is returned in the endianess of the machine the routine
102 * is running on.
103 *
104 * Returns the data read.
105 */
106SK_U32 VpdReadDWord(
107SK_AC *pAC, /* Adapters context */
108SK_IOC IoC, /* IO Context */
109int addr) /* VPD address */
110{
111 SK_U32 Rtv;
112
113 /* start VPD read */
114 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
115 ("VPD read dword at 0x%x\n",addr));
116 addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */
117
118 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);
119
120 /* ignore return code here */
121 (void)VpdWait(pAC, IoC, VPD_READ);
122
123 /* Don't swap here, it's a data stream of bytes */
124 Rtv = 0;
125
126 VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
127
128 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
129 ("VPD read dword data = 0x%x\n",Rtv));
130 return(Rtv);
131}
132
133#endif /* SKDIAG */
134
135/*
136 * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
137 * or to the I2C EEPROM.
138 *
139 * Returns number of bytes read / written.
140 */
141static int VpdWriteStream(
142SK_AC *pAC, /* Adapters context */
143SK_IOC IoC, /* IO Context */
144char *buf, /* data buffer */
145int Addr, /* VPD start address */
146int Len) /* number of bytes to read / to write */
147{
148 int i;
149 int j;
150 SK_U16 AdrReg;
151 int Rtv;
152 SK_U8 * pComp; /* Compare pointer */
153 SK_U8 Data; /* Input Data for Compare */
154
155 /* Init Compare Pointer */
156 pComp = (SK_U8 *) buf;
157
158 for (i = 0; i < Len; i++, buf++) {
159 if ((i%sizeof(SK_U32)) == 0) {
160 /*
161 * At the begin of each cycle read the Data Reg
162 * So it is initialized even if only a few bytes
163 * are written.
164 */
165 AdrReg = (SK_U16) Addr;
166 AdrReg &= ~VPD_WRITE; /* READ operation */
167
168 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
169
170 /* Wait for termination */
171 Rtv = VpdWait(pAC, IoC, VPD_READ);
172 if (Rtv != 0) {
173 return(i);
174 }
175 }
176
177 /* Write current Byte */
178 VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
179 *(SK_U8*)buf);
180
181 if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
182 /* New Address needs to be written to VPD_ADDR reg */
183 AdrReg = (SK_U16) Addr;
184 Addr += sizeof(SK_U32);
185 AdrReg |= VPD_WRITE; /* WRITE operation */
186
187 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
188
189 /* Wait for termination */
190 Rtv = VpdWait(pAC, IoC, VPD_WRITE);
191 if (Rtv != 0) {
192 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
193 ("Write Timed Out\n"));
194 return(i - (i%sizeof(SK_U32)));
195 }
196
197 /*
198 * Now re-read to verify
199 */
200 AdrReg &= ~VPD_WRITE; /* READ operation */
201
202 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
203
204 /* Wait for termination */
205 Rtv = VpdWait(pAC, IoC, VPD_READ);
206 if (Rtv != 0) {
207 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
208 ("Verify Timed Out\n"));
209 return(i - (i%sizeof(SK_U32)));
210 }
211
212 for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
213
214 VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
215
216 if (Data != *pComp) {
217 /* Verify Error */
218 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
219 ("WriteStream Verify Error\n"));
220 return(i - (i%sizeof(SK_U32)) + j);
221 }
222 }
223 }
224 }
225
226 return(Len);
227}
228
229
230/*
231 * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
232 * or to the I2C EEPROM.
233 *
234 * Returns number of bytes read / written.
235 */
236static int VpdReadStream(
237SK_AC *pAC, /* Adapters context */
238SK_IOC IoC, /* IO Context */
239char *buf, /* data buffer */
240int Addr, /* VPD start address */
241int Len) /* number of bytes to read / to write */
242{
243 int i;
244 SK_U16 AdrReg;
245 int Rtv;
246
247 for (i = 0; i < Len; i++, buf++) {
248 if ((i%sizeof(SK_U32)) == 0) {
249 /* New Address needs to be written to VPD_ADDR reg */
250 AdrReg = (SK_U16) Addr;
251 Addr += sizeof(SK_U32);
252 AdrReg &= ~VPD_WRITE; /* READ operation */
253
254 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
255
256 /* Wait for termination */
257 Rtv = VpdWait(pAC, IoC, VPD_READ);
258 if (Rtv != 0) {
259 return(i);
260 }
261 }
262 VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
263 (SK_U8 *)buf);
264 }
265
266 return(Len);
267}
268
269/*
270 * Read ore writes 'len' bytes of VPD data, starting at 'addr' from
271 * or to the I2C EEPROM.
272 *
273 * Returns number of bytes read / written.
274 */
275static int VpdTransferBlock(
276SK_AC *pAC, /* Adapters context */
277SK_IOC IoC, /* IO Context */
278char *buf, /* data buffer */
279int addr, /* VPD start address */
280int len, /* number of bytes to read / to write */
281int dir) /* transfer direction may be VPD_READ or VPD_WRITE */
282{
283 int Rtv; /* Return value */
284 int vpd_rom_size;
285
286 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
287 ("VPD %s block, addr = 0x%x, len = %d\n",
288 dir ? "write" : "read", addr, len));
289
290 if (len == 0)
291 return(0);
292
293 vpd_rom_size = pAC->vpd.rom_size;
294
295 if (addr > vpd_rom_size - 4) {
296 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
297 ("Address error: 0x%x, exp. < 0x%x\n",
298 addr, vpd_rom_size - 4));
299 return(0);
300 }
301
302 if (addr + len > vpd_rom_size) {
303 len = vpd_rom_size - addr;
304 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
305 ("Warning: len was cut to %d\n", len));
306 }
307
308 if (dir == VPD_READ) {
309 Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
310 }
311 else {
312 Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
313 }
314
315 return(Rtv);
316}
317
318#ifdef SKDIAG
319
320/*
321 * Read 'len' bytes of VPD data, starting at 'addr'.
322 *
323 * Returns number of bytes read.
324 */
325int VpdReadBlock(
326SK_AC *pAC, /* pAC pointer */
327SK_IOC IoC, /* IO Context */
328char *buf, /* buffer were the data should be stored */
329int addr, /* start reading at the VPD address */
330int len) /* number of bytes to read */
331{
332 return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
333}
334
335/*
336 * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
337 *
338 * Returns number of bytes writes.
339 */
340int VpdWriteBlock(
341SK_AC *pAC, /* pAC pointer */
342SK_IOC IoC, /* IO Context */
343char *buf, /* buffer, holds the data to write */
344int addr, /* start writing at the VPD address */
345int len) /* number of bytes to write */
346{
347 return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
348}
349#endif /* SKDIAG */
350
351/*
352 * (re)initialize the VPD buffer
353 *
354 * Reads the VPD data from the EEPROM into the VPD buffer.
355 * Get the remaining read only and read / write space.
356 *
357 * return 0: success
358 * 1: fatal VPD error
359 */
360static int VpdInit(
361SK_AC *pAC, /* Adapters context */
362SK_IOC IoC) /* IO Context */
363{
364 SK_VPD_PARA *r, rp; /* RW or RV */
365 int i;
366 unsigned char x;
367 int vpd_size;
368 SK_U16 dev_id;
369 SK_U32 our_reg2;
370
371 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
372
373 VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
374
375 VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
376
377 pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
378
379 /*
380 * this function might get used before the hardware is initialized
381 * therefore we cannot always trust in GIChipId
382 */
383 if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
384 dev_id != VPD_DEV_ID_GENESIS) ||
385 ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
386 !pAC->GIni.GIGenesis)) {
387
388 /* for Yukon the VPD size is always 256 */
389 vpd_size = VPD_SIZE_YUKON;
390 }
391 else {
392 /* Genesis uses the maximum ROM size up to 512 for VPD */
393 if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
394 vpd_size = VPD_SIZE_GENESIS;
395 }
396 else {
397 vpd_size = pAC->vpd.rom_size;
398 }
399 }
400
401 /* read the VPD data into the VPD buffer */
402 if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
403 != vpd_size) {
404
405 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
406 ("Block Read Error\n"));
407 return(1);
408 }
409
410 pAC->vpd.vpd_size = vpd_size;
411
412 /* Asus K8V Se Deluxe bugfix. Correct VPD content */
413 /* MBo April 2004 */
414 if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) &&
415 ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) &&
416 ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) {
417 printk("sk98lin: Asus mainboard with buggy VPD? "
418 "Correcting data.\n");
419 pAC->vpd.vpd_buf[0x40] = 0x38;
420 }
421
422
423 /* find the end tag of the RO area */
424 if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
425 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
426 ("Encoding Error: RV Tag not found\n"));
427 return(1);
428 }
429
430 if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
431 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
432 ("Encoding Error: Invalid VPD struct size\n"));
433 return(1);
434 }
435 pAC->vpd.v.vpd_free_ro = r->p_len - 1;
436
437 /* test the checksum */
438 for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
439 x += pAC->vpd.vpd_buf[i];
440 }
441
442 if (x != 0) {
443 /* checksum error */
444 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
445 ("VPD Checksum Error\n"));
446 return(1);
447 }
448
449 /* find and check the end tag of the RW area */
450 if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
451 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
452 ("Encoding Error: RV Tag not found\n"));
453 return(1);
454 }
455
456 if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
457 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
458 ("Encoding Error: Invalid VPD struct size\n"));
459 return(1);
460 }
461 pAC->vpd.v.vpd_free_rw = r->p_len;
462
463 /* everything seems to be ok */
464 if (pAC->GIni.GIChipId != 0) {
465 pAC->vpd.v.vpd_status |= VPD_VALID;
466 }
467
468 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
469 ("done. Free RO = %d, Free RW = %d\n",
470 pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
471
472 return(0);
473}
474
475/*
476 * find the Keyword 'key' in the VPD buffer and fills the
477 * parameter struct 'p' with it's values
478 *
479 * returns *p success
480 * 0: parameter was not found or VPD encoding error
481 */
482static SK_VPD_PARA *vpd_find_para(
483SK_AC *pAC, /* common data base */
484const char *key, /* keyword to find (e.g. "MN") */
485SK_VPD_PARA *p) /* parameter description struct */
486{
487 char *v ; /* points to VPD buffer */
488 int max; /* Maximum Number of Iterations */
489
490 v = pAC->vpd.vpd_buf;
491 max = 128;
492
493 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
494 ("VPD find para %s .. ",key));
495
496 /* check mandatory resource type ID string (Product Name) */
497 if (*v != (char)RES_ID) {
498 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
499 ("Error: 0x%x missing\n", RES_ID));
500 return NULL;
501 }
502
503 if (strcmp(key, VPD_NAME) == 0) {
504 p->p_len = VPD_GET_RES_LEN(v);
505 p->p_val = VPD_GET_VAL(v);
506 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
507 ("found, len = %d\n", p->p_len));
508 return(p);
509 }
510
511 v += 3 + VPD_GET_RES_LEN(v) + 3;
512 for (;; ) {
513 if (SK_MEMCMP(key,v,2) == 0) {
514 p->p_len = VPD_GET_VPD_LEN(v);
515 p->p_val = VPD_GET_VAL(v);
516 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
517 ("found, len = %d\n",p->p_len));
518 return(p);
519 }
520
521 /* exit when reaching the "RW" Tag or the maximum of itera. */
522 max--;
523 if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
524 break;
525 }
526
527 if (SK_MEMCMP(VPD_RV,v,2) == 0) {
528 v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
529 }
530 else {
531 v += 3 + VPD_GET_VPD_LEN(v);
532 }
533 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
534 ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
535 }
536
537#ifdef DEBUG
538 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
539 if (max == 0) {
540 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
541 ("Key/Len Encoding error\n"));
542 }
543#endif /* DEBUG */
544 return NULL;
545}
546
547/*
548 * Move 'n' bytes. Begin with the last byte if 'n' is > 0,
549 * Start with the last byte if n is < 0.
550 *
551 * returns nothing
552 */
553static void vpd_move_para(
554char *start, /* start of memory block */
555char *end, /* end of memory block to move */
556int n) /* number of bytes the memory block has to be moved */
557{
558 char *p;
559 int i; /* number of byte copied */
560
561 if (n == 0)
562 return;
563
564 i = (int) (end - start + 1);
565 if (n < 0) {
566 p = start + n;
567 while (i != 0) {
568 *p++ = *start++;
569 i--;
570 }
571 }
572 else {
573 p = end + n;
574 while (i != 0) {
575 *p-- = *end--;
576 i--;
577 }
578 }
579}
580
581/*
582 * setup the VPD keyword 'key' at 'ip'.
583 *
584 * returns nothing
585 */
586static void vpd_insert_key(
587const char *key, /* keyword to insert */
588const char *buf, /* buffer with the keyword value */
589int len, /* length of the value string */
590char *ip) /* inseration point */
591{
592 SK_VPD_KEY *p;
593
594 p = (SK_VPD_KEY *) ip;
595 p->p_key[0] = key[0];
596 p->p_key[1] = key[1];
597 p->p_len = (unsigned char) len;
598 SK_MEMCPY(&p->p_val,buf,len);
599}
600
601/*
602 * Setup the VPD end tag "RV" / "RW".
603 * Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
604 *
605 * returns 0: success
606 * 1: encoding error
607 */
608static int vpd_mod_endtag(
609SK_AC *pAC, /* common data base */
610char *etp) /* end pointer input position */
611{
612 SK_VPD_KEY *p;
613 unsigned char x;
614 int i;
615 int vpd_size;
616
617 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
618 ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
619
620 vpd_size = pAC->vpd.vpd_size;
621
622 p = (SK_VPD_KEY *) etp;
623
624 if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
625 /* something wrong here, encoding error */
626 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
627 ("Encoding Error: invalid end tag\n"));
628 return(1);
629 }
630 if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
631 /* create "RW" tag */
632 p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
633 pAC->vpd.v.vpd_free_rw = (int) p->p_len;
634 i = pAC->vpd.v.vpd_free_rw;
635 etp += 3;
636 }
637 else {
638 /* create "RV" tag */
639 p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
640 pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
641
642 /* setup checksum */
643 for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
644 x += pAC->vpd.vpd_buf[i];
645 }
646 p->p_val = (char) 0 - x;
647 i = pAC->vpd.v.vpd_free_ro;
648 etp += 4;
649 }
650 while (i) {
651 *etp++ = 0x00;
652 i--;
653 }
654
655 return(0);
656}
657
658/*
659 * Insert a VPD keyword into the VPD buffer.
660 *
661 * The keyword 'key' is inserted at the position 'ip' in the
662 * VPD buffer.
663 * The keywords behind the input position will
664 * be moved. The VPD end tag "RV" or "RW" is generated again.
665 *
666 * returns 0: success
667 * 2: value string was cut
668 * 4: VPD full, keyword was not written
669 * 6: fatal VPD error
670 *
671 */
672static int VpdSetupPara(
673SK_AC *pAC, /* common data base */
674const char *key, /* keyword to insert */
675const char *buf, /* buffer with the keyword value */
676int len, /* length of the keyword value */
677int type, /* VPD_RO_KEY or VPD_RW_KEY */
678int op) /* operation to do: ADD_KEY or OWR_KEY */
679{
680 SK_VPD_PARA vp;
681 char *etp; /* end tag position */
682 int free; /* remaining space in selected area */
683 char *ip; /* input position inside the VPD buffer */
684 int rtv; /* return code */
685 int head; /* additional haeder bytes to move */
686 int found; /* additinoal bytes if the keyword was found */
687 int vpd_size;
688
689 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
690 ("VPD setup para key = %s, val = %s\n",key,buf));
691
692 vpd_size = pAC->vpd.vpd_size;
693
694 rtv = 0;
695 ip = NULL;
696 if (type == VPD_RW_KEY) {
697 /* end tag is "RW" */
698 free = pAC->vpd.v.vpd_free_rw;
699 etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
700 }
701 else {
702 /* end tag is "RV" */
703 free = pAC->vpd.v.vpd_free_ro;
704 etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
705 }
706 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
707 ("Free RO = %d, Free RW = %d\n",
708 pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
709
710 head = 0;
711 found = 0;
712 if (op == OWR_KEY) {
713 if (vpd_find_para(pAC, key, &vp)) {
714 found = 3;
715 ip = vp.p_val - 3;
716 free += vp.p_len + 3;
717 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
718 ("Overwrite Key\n"));
719 }
720 else {
721 op = ADD_KEY;
722 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
723 ("Add Key\n"));
724 }
725 }
726 if (op == ADD_KEY) {
727 ip = etp;
728 vp.p_len = 0;
729 head = 3;
730 }
731
732 if (len + 3 > free) {
733 if (free < 7) {
734 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
735 ("VPD Buffer Overflow, keyword not written\n"));
736 return(4);
737 }
738 /* cut it again */
739 len = free - 3;
740 rtv = 2;
741 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
742 ("VPD Buffer Full, Keyword was cut\n"));
743 }
744
745 vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
746 vpd_insert_key(key, buf, len, ip);
747 if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
748 pAC->vpd.v.vpd_status &= ~VPD_VALID;
749 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
750 ("VPD Encoding Error\n"));
751 return(6);
752 }
753
754 return(rtv);
755}
756
757
758/*
759 * Read the contents of the VPD EEPROM and copy it to the
760 * VPD buffer if not already done.
761 *
762 * return: A pointer to the vpd_status structure. The structure contains
763 * this fields.
764 */
765SK_VPD_STATUS *VpdStat(
766SK_AC *pAC, /* Adapters context */
767SK_IOC IoC) /* IO Context */
768{
769 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
770 (void)VpdInit(pAC, IoC);
771 }
772 return(&pAC->vpd.v);
773}
774
775
776/*
777 * Read the contents of the VPD EEPROM and copy it to the VPD
778 * buffer if not already done.
779 * Scan the VPD buffer for VPD keywords and create the VPD
780 * keyword list by copying the keywords to 'buf', all after
781 * each other and terminated with a '\0'.
782 *
783 * Exceptions: o The Resource Type ID String (product name) is called "Name"
784 * o The VPD end tags 'RV' and 'RW' are not listed
785 *
786 * The number of copied keywords is counted in 'elements'.
787 *
788 * returns 0: success
789 * 2: buffer overfull, one or more keywords are missing
790 * 6: fatal VPD error
791 *
792 * example values after returning:
793 *
794 * buf = "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
795 * *len = 30
796 * *elements = 9
797 */
798int VpdKeys(
799SK_AC *pAC, /* common data base */
800SK_IOC IoC, /* IO Context */
801char *buf, /* buffer where to copy the keywords */
802int *len, /* buffer length */
803int *elements) /* number of keywords returned */
804{
805 char *v;
806 int n;
807
808 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
809 *elements = 0;
810 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
811 if (VpdInit(pAC, IoC) != 0) {
812 *len = 0;
813 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
814 ("VPD Init Error, terminated\n"));
815 return(6);
816 }
817 }
818
819 if ((signed)strlen(VPD_NAME) + 1 <= *len) {
820 v = pAC->vpd.vpd_buf;
821 strcpy(buf,VPD_NAME);
822 n = strlen(VPD_NAME) + 1;
823 buf += n;
824 *elements = 1;
825 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
826 ("'%c%c' ",v[0],v[1]));
827 }
828 else {
829 *len = 0;
830 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
831 ("buffer overflow\n"));
832 return(2);
833 }
834
835 v += 3 + VPD_GET_RES_LEN(v) + 3;
836 for (;; ) {
837 /* exit when reaching the "RW" Tag */
838 if (SK_MEMCMP(VPD_RW,v,2) == 0) {
839 break;
840 }
841
842 if (SK_MEMCMP(VPD_RV,v,2) == 0) {
843 v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
844 continue;
845 }
846
847 if (n+3 <= *len) {
848 SK_MEMCPY(buf,v,2);
849 buf += 2;
850 *buf++ = '\0';
851 n += 3;
852 v += 3 + VPD_GET_VPD_LEN(v);
853 *elements += 1;
854 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
855 ("'%c%c' ",v[0],v[1]));
856 }
857 else {
858 *len = n;
859 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
860 ("buffer overflow\n"));
861 return(2);
862 }
863 }
864
865 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
866 *len = n;
867 return(0);
868}
869
870
871/*
872 * Read the contents of the VPD EEPROM and copy it to the
873 * VPD buffer if not already done. Search for the VPD keyword
874 * 'key' and copy its value to 'buf'. Add a terminating '\0'.
875 * If the value does not fit into the buffer cut it after
876 * 'len' - 1 bytes.
877 *
878 * returns 0: success
879 * 1: keyword not found
880 * 2: value string was cut
881 * 3: VPD transfer timeout
882 * 6: fatal VPD error
883 */
884int VpdRead(
885SK_AC *pAC, /* common data base */
886SK_IOC IoC, /* IO Context */
887const char *key, /* keyword to read (e.g. "MN") */
888char *buf, /* buffer where to copy the keyword value */
889int *len) /* buffer length */
890{
891 SK_VPD_PARA *p, vp;
892
893 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
894 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
895 if (VpdInit(pAC, IoC) != 0) {
896 *len = 0;
897 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
898 ("VPD init error\n"));
899 return(6);
900 }
901 }
902
903 if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
904 if (p->p_len > (*(unsigned *)len)-1) {
905 p->p_len = *len - 1;
906 }
907 SK_MEMCPY(buf, p->p_val, p->p_len);
908 buf[p->p_len] = '\0';
909 *len = p->p_len;
910 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
911 ("%c%c%c%c.., len = %d\n",
912 buf[0],buf[1],buf[2],buf[3],*len));
913 }
914 else {
915 *len = 0;
916 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
917 return(1);
918 }
919 return(0);
920}
921
922
923/*
924 * Check whether a given key may be written
925 *
926 * returns
927 * SK_TRUE Yes it may be written
928 * SK_FALSE No it may be written
929 */
930SK_BOOL VpdMayWrite(
931char *key) /* keyword to write (allowed values "Yx", "Vx") */
932{
933 if ((*key != 'Y' && *key != 'V') ||
934 key[1] < '0' || key[1] > 'Z' ||
935 (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
936
937 return(SK_FALSE);
938 }
939 return(SK_TRUE);
940}
941
942/*
943 * Read the contents of the VPD EEPROM and copy it to the VPD
944 * buffer if not already done. Insert/overwrite the keyword 'key'
945 * in the VPD buffer. Cut the keyword value if it does not fit
946 * into the VPD read / write area.
947 *
948 * returns 0: success
949 * 2: value string was cut
950 * 3: VPD transfer timeout
951 * 4: VPD full, keyword was not written
952 * 5: keyword cannot be written
953 * 6: fatal VPD error
954 */
955int VpdWrite(
956SK_AC *pAC, /* common data base */
957SK_IOC IoC, /* IO Context */
958const char *key, /* keyword to write (allowed values "Yx", "Vx") */
959const char *buf) /* buffer where the keyword value can be read from */
960{
961 int len; /* length of the keyword to write */
962 int rtv; /* return code */
963 int rtv2;
964
965 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
966 ("VPD write %s = %s\n",key,buf));
967
968 if ((*key != 'Y' && *key != 'V') ||
969 key[1] < '0' || key[1] > 'Z' ||
970 (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
971
972 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
973 ("illegal key tag, keyword not written\n"));
974 return(5);
975 }
976
977 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
978 if (VpdInit(pAC, IoC) != 0) {
979 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
980 ("VPD init error\n"));
981 return(6);
982 }
983 }
984
985 rtv = 0;
986 len = strlen(buf);
987 if (len > VPD_MAX_LEN) {
988 /* cut it */
989 len = VPD_MAX_LEN;
990 rtv = 2;
991 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
992 ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
993 }
994 if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
995 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
996 ("VPD write error\n"));
997 return(rtv2);
998 }
999
1000 return(rtv);
1001}
1002
1003/*
1004 * Read the contents of the VPD EEPROM and copy it to the
1005 * VPD buffer if not already done. Remove the VPD keyword
1006 * 'key' from the VPD buffer.
1007 * Only the keywords in the read/write area can be deleted.
1008 * Keywords in the read only area cannot be deleted.
1009 *
1010 * returns 0: success, keyword was removed
1011 * 1: keyword not found
1012 * 5: keyword cannot be deleted
1013 * 6: fatal VPD error
1014 */
1015int VpdDelete(
1016SK_AC *pAC, /* common data base */
1017SK_IOC IoC, /* IO Context */
1018char *key) /* keyword to read (e.g. "MN") */
1019{
1020 SK_VPD_PARA *p, vp;
1021 char *etp;
1022 int vpd_size;
1023
1024 vpd_size = pAC->vpd.vpd_size;
1025
1026 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
1027 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
1028 if (VpdInit(pAC, IoC) != 0) {
1029 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1030 ("VPD init error\n"));
1031 return(6);
1032 }
1033 }
1034
1035 if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
1036 if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
1037 /* try to delete read only keyword */
1038 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1039 ("cannot delete RO keyword\n"));
1040 return(5);
1041 }
1042
1043 etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);
1044
1045 vpd_move_para(vp.p_val+vp.p_len, etp+2,
1046 - ((int)(vp.p_len + 3)));
1047 if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
1048 pAC->vpd.v.vpd_status &= ~VPD_VALID;
1049 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1050 ("VPD encoding error\n"));
1051 return(6);
1052 }
1053 }
1054 else {
1055 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1056 ("keyword not found\n"));
1057 return(1);
1058 }
1059
1060 return(0);
1061}
1062
1063/*
1064 * If the VPD buffer contains valid data write the VPD
1065 * read/write area back to the VPD EEPROM.
1066 *
1067 * returns 0: success
1068 * 3: VPD transfer timeout
1069 */
1070int VpdUpdate(
1071SK_AC *pAC, /* Adapters context */
1072SK_IOC IoC) /* IO Context */
1073{
1074 int vpd_size;
1075
1076 vpd_size = pAC->vpd.vpd_size;
1077
1078 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
1079 if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
1080 if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
1081 vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {
1082
1083 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1084 ("transfer timed out\n"));
1085 return(3);
1086 }
1087 }
1088 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
1089 return(0);
1090}
1091
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
deleted file mode 100644
index b4e75022a657..000000000000
--- a/drivers/net/sk98lin/skxmac2.c
+++ /dev/null
@@ -1,4160 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skxmac2.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.102 $
6 * Date: $Date: 2003/10/02 16:53:58 $
7 * Purpose: Contains functions to initialize the MACs and PHYs
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#include "h/skdrv1st.h"
26#include "h/skdrv2nd.h"
27
28/* typedefs *******************************************************************/
29
30/* BCOM PHY magic pattern list */
31typedef struct s_PhyHack {
32 int PhyReg; /* Phy register */
33 SK_U16 PhyVal; /* Value to write */
34} BCOM_HACK;
35
36/* local variables ************************************************************/
37
38#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
39static const char SysKonnectFileId[] =
40 "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
41#endif
42
43#ifdef GENESIS
44static BCOM_HACK BcomRegA1Hack[] = {
45 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
46 { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
47 { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
48 { 0, 0 }
49};
50static BCOM_HACK BcomRegC0Hack[] = {
51 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
52 { 0x15, 0x0A04 }, { 0x18, 0x0420 },
53 { 0, 0 }
54};
55#endif
56
57/* function prototypes ********************************************************/
58#ifdef GENESIS
59static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
60static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
61static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
62static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
63#endif /* GENESIS */
64#ifdef YUKON
65static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
66static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
67#endif /* YUKON */
68#ifdef OTHER_PHY
69static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
70static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
71static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
72static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
73#endif /* OTHER_PHY */
74
75
76#ifdef GENESIS
77/******************************************************************************
78 *
79 * SkXmPhyRead() - Read from XMAC PHY register
80 *
81 * Description: reads a 16-bit word from XMAC PHY or ext. PHY
82 *
83 * Returns:
84 * nothing
85 */
86void SkXmPhyRead(
87SK_AC *pAC, /* Adapter Context */
88SK_IOC IoC, /* I/O Context */
89int Port, /* Port Index (MAC_1 + n) */
90int PhyReg, /* Register Address (Offset) */
91SK_U16 SK_FAR *pVal) /* Pointer to Value */
92{
93 SK_U16 Mmu;
94 SK_GEPORT *pPrt;
95
96 pPrt = &pAC->GIni.GP[Port];
97
98 /* write the PHY register's address */
99 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
100
101 /* get the PHY register's value */
102 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
103
104 if (pPrt->PhyType != SK_PHY_XMAC) {
105 do {
106 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
107 /* wait until 'Ready' is set */
108 } while ((Mmu & XM_MMU_PHY_RDY) == 0);
109
110 /* get the PHY register's value */
111 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
112 }
113} /* SkXmPhyRead */
114
115
116/******************************************************************************
117 *
118 * SkXmPhyWrite() - Write to XMAC PHY register
119 *
120 * Description: writes a 16-bit word to XMAC PHY or ext. PHY
121 *
122 * Returns:
123 * nothing
124 */
125void SkXmPhyWrite(
126SK_AC *pAC, /* Adapter Context */
127SK_IOC IoC, /* I/O Context */
128int Port, /* Port Index (MAC_1 + n) */
129int PhyReg, /* Register Address (Offset) */
130SK_U16 Val) /* Value */
131{
132 SK_U16 Mmu;
133 SK_GEPORT *pPrt;
134
135 pPrt = &pAC->GIni.GP[Port];
136
137 if (pPrt->PhyType != SK_PHY_XMAC) {
138 do {
139 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
140 /* wait until 'Busy' is cleared */
141 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
142 }
143
144 /* write the PHY register's address */
145 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
146
147 /* write the PHY register's value */
148 XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
149
150 if (pPrt->PhyType != SK_PHY_XMAC) {
151 do {
152 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
153 /* wait until 'Busy' is cleared */
154 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
155 }
156} /* SkXmPhyWrite */
157#endif /* GENESIS */
158
159
160#ifdef YUKON
161/******************************************************************************
162 *
163 * SkGmPhyRead() - Read from GPHY register
164 *
165 * Description: reads a 16-bit word from GPHY through MDIO
166 *
167 * Returns:
168 * nothing
169 */
170void SkGmPhyRead(
171SK_AC *pAC, /* Adapter Context */
172SK_IOC IoC, /* I/O Context */
173int Port, /* Port Index (MAC_1 + n) */
174int PhyReg, /* Register Address (Offset) */
175SK_U16 SK_FAR *pVal) /* Pointer to Value */
176{
177 SK_U16 Ctrl;
178 SK_GEPORT *pPrt;
179#ifdef VCPU
180 u_long SimCyle;
181 u_long SimLowTime;
182
183 VCPUgetTime(&SimCyle, &SimLowTime);
184 VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
185 PhyReg, SimCyle, SimLowTime);
186#endif /* VCPU */
187
188 pPrt = &pAC->GIni.GP[Port];
189
190 /* set PHY-Register offset and 'Read' OpCode (= 1) */
191 *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
192 GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
193
194 GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
195
196 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
197
198 /* additional check for MDC/MDIO activity */
199 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
200 *pVal = 0;
201 return;
202 }
203
204 *pVal |= GM_SMI_CT_BUSY;
205
206 do {
207#ifdef VCPU
208 VCPUwaitTime(1000);
209#endif /* VCPU */
210
211 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
212
213 /* wait until 'ReadValid' is set */
214 } while (Ctrl == *pVal);
215
216 /* get the PHY register's value */
217 GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
218
219#ifdef VCPU
220 VCPUgetTime(&SimCyle, &SimLowTime);
221 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
222 SimCyle, SimLowTime);
223#endif /* VCPU */
224
225} /* SkGmPhyRead */
226
227
228/******************************************************************************
229 *
230 * SkGmPhyWrite() - Write to GPHY register
231 *
232 * Description: writes a 16-bit word to GPHY through MDIO
233 *
234 * Returns:
235 * nothing
236 */
237void SkGmPhyWrite(
238SK_AC *pAC, /* Adapter Context */
239SK_IOC IoC, /* I/O Context */
240int Port, /* Port Index (MAC_1 + n) */
241int PhyReg, /* Register Address (Offset) */
242SK_U16 Val) /* Value */
243{
244 SK_U16 Ctrl;
245 SK_GEPORT *pPrt;
246#ifdef VCPU
247 SK_U32 DWord;
248 u_long SimCyle;
249 u_long SimLowTime;
250
251 VCPUgetTime(&SimCyle, &SimLowTime);
252 VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
253 PhyReg, Val, SimCyle, SimLowTime);
254#endif /* VCPU */
255
256 pPrt = &pAC->GIni.GP[Port];
257
258 /* write the PHY register's value */
259 GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
260
261 /* set PHY-Register offset and 'Write' OpCode (= 0) */
262 Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
263
264 GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
265
266 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
267
268 /* additional check for MDC/MDIO activity */
269 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
270 return;
271 }
272
273 Val |= GM_SMI_CT_BUSY;
274
275 do {
276#ifdef VCPU
277 /* read Timer value */
278 SK_IN32(IoC, B2_TI_VAL, &DWord);
279
280 VCPUwaitTime(1000);
281#endif /* VCPU */
282
283 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
284
285 /* wait until 'Busy' is cleared */
286 } while (Ctrl == Val);
287
288#ifdef VCPU
289 VCPUgetTime(&SimCyle, &SimLowTime);
290 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
291 SimCyle, SimLowTime);
292#endif /* VCPU */
293
294} /* SkGmPhyWrite */
295#endif /* YUKON */
296
297
298#ifdef SK_DIAG
299/******************************************************************************
300 *
301 * SkGePhyRead() - Read from PHY register
302 *
303 * Description: calls a read PHY routine dep. on board type
304 *
305 * Returns:
306 * nothing
307 */
308void SkGePhyRead(
309SK_AC *pAC, /* Adapter Context */
310SK_IOC IoC, /* I/O Context */
311int Port, /* Port Index (MAC_1 + n) */
312int PhyReg, /* Register Address (Offset) */
313SK_U16 *pVal) /* Pointer to Value */
314{
315 void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
316
317 if (pAC->GIni.GIGenesis) {
318 r_func = SkXmPhyRead;
319 }
320 else {
321 r_func = SkGmPhyRead;
322 }
323
324 r_func(pAC, IoC, Port, PhyReg, pVal);
325} /* SkGePhyRead */
326
327
328/******************************************************************************
329 *
330 * SkGePhyWrite() - Write to PHY register
331 *
332 * Description: calls a write PHY routine dep. on board type
333 *
334 * Returns:
335 * nothing
336 */
337void SkGePhyWrite(
338SK_AC *pAC, /* Adapter Context */
339SK_IOC IoC, /* I/O Context */
340int Port, /* Port Index (MAC_1 + n) */
341int PhyReg, /* Register Address (Offset) */
342SK_U16 Val) /* Value */
343{
344 void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
345
346 if (pAC->GIni.GIGenesis) {
347 w_func = SkXmPhyWrite;
348 }
349 else {
350 w_func = SkGmPhyWrite;
351 }
352
353 w_func(pAC, IoC, Port, PhyReg, Val);
354} /* SkGePhyWrite */
355#endif /* SK_DIAG */
356
357
358/******************************************************************************
359 *
360 * SkMacPromiscMode() - Enable / Disable Promiscuous Mode
361 *
362 * Description:
363 * enables / disables promiscuous mode by setting Mode Register (XMAC) or
364 * Receive Control Register (GMAC) dep. on board type
365 *
366 * Returns:
367 * nothing
368 */
369void SkMacPromiscMode(
370SK_AC *pAC, /* adapter context */
371SK_IOC IoC, /* IO context */
372int Port, /* Port Index (MAC_1 + n) */
373SK_BOOL Enable) /* Enable / Disable */
374{
375#ifdef YUKON
376 SK_U16 RcReg;
377#endif
378#ifdef GENESIS
379 SK_U32 MdReg;
380#endif
381
382#ifdef GENESIS
383 if (pAC->GIni.GIGenesis) {
384
385 XM_IN32(IoC, Port, XM_MODE, &MdReg);
386 /* enable or disable promiscuous mode */
387 if (Enable) {
388 MdReg |= XM_MD_ENA_PROM;
389 }
390 else {
391 MdReg &= ~XM_MD_ENA_PROM;
392 }
393 /* setup Mode Register */
394 XM_OUT32(IoC, Port, XM_MODE, MdReg);
395 }
396#endif /* GENESIS */
397
398#ifdef YUKON
399 if (pAC->GIni.GIYukon) {
400
401 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
402
403 /* enable or disable unicast and multicast filtering */
404 if (Enable) {
405 RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
406 }
407 else {
408 RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
409 }
410 /* setup Receive Control Register */
411 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
412 }
413#endif /* YUKON */
414
415} /* SkMacPromiscMode*/
416
417
418/******************************************************************************
419 *
420 * SkMacHashing() - Enable / Disable Hashing
421 *
422 * Description:
423 * enables / disables hashing by setting Mode Register (XMAC) or
424 * Receive Control Register (GMAC) dep. on board type
425 *
426 * Returns:
427 * nothing
428 */
429void SkMacHashing(
430SK_AC *pAC, /* adapter context */
431SK_IOC IoC, /* IO context */
432int Port, /* Port Index (MAC_1 + n) */
433SK_BOOL Enable) /* Enable / Disable */
434{
435#ifdef YUKON
436 SK_U16 RcReg;
437#endif
438#ifdef GENESIS
439 SK_U32 MdReg;
440#endif
441
442#ifdef GENESIS
443 if (pAC->GIni.GIGenesis) {
444
445 XM_IN32(IoC, Port, XM_MODE, &MdReg);
446 /* enable or disable hashing */
447 if (Enable) {
448 MdReg |= XM_MD_ENA_HASH;
449 }
450 else {
451 MdReg &= ~XM_MD_ENA_HASH;
452 }
453 /* setup Mode Register */
454 XM_OUT32(IoC, Port, XM_MODE, MdReg);
455 }
456#endif /* GENESIS */
457
458#ifdef YUKON
459 if (pAC->GIni.GIYukon) {
460
461 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
462
463 /* enable or disable multicast filtering */
464 if (Enable) {
465 RcReg |= GM_RXCR_MCF_ENA;
466 }
467 else {
468 RcReg &= ~GM_RXCR_MCF_ENA;
469 }
470 /* setup Receive Control Register */
471 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
472 }
473#endif /* YUKON */
474
475} /* SkMacHashing*/
476
477
478#ifdef SK_DIAG
479/******************************************************************************
480 *
481 * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
482 *
483 * Description:
484 * The features
485 * - FCS stripping, SK_STRIP_FCS_ON/OFF
486 * - pad byte stripping, SK_STRIP_PAD_ON/OFF
487 * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF
488 * for inrange length error frames
489 * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF
490 * for frames > 1514 bytes
491 * - enable Rx of own packets SK_SELF_RX_ON/OFF
492 *
493 * for incoming packets may be enabled/disabled by this function.
494 * Additional modes may be added later.
495 * Multiple modes can be enabled/disabled at the same time.
496 * The new configuration is written to the Rx Command register immediately.
497 *
498 * Returns:
499 * nothing
500 */
501static void SkXmSetRxCmd(
502SK_AC *pAC, /* adapter context */
503SK_IOC IoC, /* IO context */
504int Port, /* Port Index (MAC_1 + n) */
505int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
506 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
507{
508 SK_U16 OldRxCmd;
509 SK_U16 RxCmd;
510
511 XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
512
513 RxCmd = OldRxCmd;
514
515 switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
516 case SK_STRIP_FCS_ON:
517 RxCmd |= XM_RX_STRIP_FCS;
518 break;
519 case SK_STRIP_FCS_OFF:
520 RxCmd &= ~XM_RX_STRIP_FCS;
521 break;
522 }
523
524 switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
525 case SK_STRIP_PAD_ON:
526 RxCmd |= XM_RX_STRIP_PAD;
527 break;
528 case SK_STRIP_PAD_OFF:
529 RxCmd &= ~XM_RX_STRIP_PAD;
530 break;
531 }
532
533 switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
534 case SK_LENERR_OK_ON:
535 RxCmd |= XM_RX_LENERR_OK;
536 break;
537 case SK_LENERR_OK_OFF:
538 RxCmd &= ~XM_RX_LENERR_OK;
539 break;
540 }
541
542 switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
543 case SK_BIG_PK_OK_ON:
544 RxCmd |= XM_RX_BIG_PK_OK;
545 break;
546 case SK_BIG_PK_OK_OFF:
547 RxCmd &= ~XM_RX_BIG_PK_OK;
548 break;
549 }
550
551 switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
552 case SK_SELF_RX_ON:
553 RxCmd |= XM_RX_SELF_RX;
554 break;
555 case SK_SELF_RX_OFF:
556 RxCmd &= ~XM_RX_SELF_RX;
557 break;
558 }
559
560 /* Write the new mode to the Rx command register if required */
561 if (OldRxCmd != RxCmd) {
562 XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
563 }
564} /* SkXmSetRxCmd */
565
566
567/******************************************************************************
568 *
569 * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
570 *
571 * Description:
572 * The features
573 * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF
574 * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF
575 * for frames > 1514 bytes
576 * - enable Rx of own packets SK_SELF_RX_ON/OFF
577 *
578 * for incoming packets may be enabled/disabled by this function.
579 * Additional modes may be added later.
580 * Multiple modes can be enabled/disabled at the same time.
581 * The new configuration is written to the Rx Command register immediately.
582 *
583 * Returns:
584 * nothing
585 */
586static void SkGmSetRxCmd(
587SK_AC *pAC, /* adapter context */
588SK_IOC IoC, /* IO context */
589int Port, /* Port Index (MAC_1 + n) */
590int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
591 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
592{
593 SK_U16 OldRxCmd;
594 SK_U16 RxCmd;
595
596 if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
597
598 GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
599
600 RxCmd = OldRxCmd;
601
602 if ((Mode & SK_STRIP_FCS_ON) != 0) {
603 RxCmd |= GM_RXCR_CRC_DIS;
604 }
605 else {
606 RxCmd &= ~GM_RXCR_CRC_DIS;
607 }
608 /* Write the new mode to the Rx control register if required */
609 if (OldRxCmd != RxCmd) {
610 GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
611 }
612 }
613
614 if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
615
616 GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
617
618 RxCmd = OldRxCmd;
619
620 if ((Mode & SK_BIG_PK_OK_ON) != 0) {
621 RxCmd |= GM_SMOD_JUMBO_ENA;
622 }
623 else {
624 RxCmd &= ~GM_SMOD_JUMBO_ENA;
625 }
626 /* Write the new mode to the Rx control register if required */
627 if (OldRxCmd != RxCmd) {
628 GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
629 }
630 }
631} /* SkGmSetRxCmd */
632
633
634/******************************************************************************
635 *
636 * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
637 *
638 * Description: modifies the MAC's Rx Control reg. dep. on board type
639 *
640 * Returns:
641 * nothing
642 */
643void SkMacSetRxCmd(
644SK_AC *pAC, /* adapter context */
645SK_IOC IoC, /* IO context */
646int Port, /* Port Index (MAC_1 + n) */
647int Mode) /* Rx Mode */
648{
649 if (pAC->GIni.GIGenesis) {
650
651 SkXmSetRxCmd(pAC, IoC, Port, Mode);
652 }
653 else {
654
655 SkGmSetRxCmd(pAC, IoC, Port, Mode);
656 }
657
658} /* SkMacSetRxCmd */
659
660
661/******************************************************************************
662 *
663 * SkMacCrcGener() - Enable / Disable CRC Generation
664 *
665 * Description: enables / disables CRC generation dep. on board type
666 *
667 * Returns:
668 * nothing
669 */
670void SkMacCrcGener(
671SK_AC *pAC, /* adapter context */
672SK_IOC IoC, /* IO context */
673int Port, /* Port Index (MAC_1 + n) */
674SK_BOOL Enable) /* Enable / Disable */
675{
676 SK_U16 Word;
677
678 if (pAC->GIni.GIGenesis) {
679
680 XM_IN16(IoC, Port, XM_TX_CMD, &Word);
681
682 if (Enable) {
683 Word &= ~XM_TX_NO_CRC;
684 }
685 else {
686 Word |= XM_TX_NO_CRC;
687 }
688 /* setup Tx Command Register */
689 XM_OUT16(IoC, Port, XM_TX_CMD, Word);
690 }
691 else {
692
693 GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
694
695 if (Enable) {
696 Word &= ~GM_TXCR_CRC_DIS;
697 }
698 else {
699 Word |= GM_TXCR_CRC_DIS;
700 }
701 /* setup Tx Control Register */
702 GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
703 }
704
705} /* SkMacCrcGener*/
706
707#endif /* SK_DIAG */
708
709
710#ifdef GENESIS
711/******************************************************************************
712 *
713 * SkXmClrExactAddr() - Clear Exact Match Address Registers
714 *
715 * Description:
716 * All Exact Match Address registers of the XMAC 'Port' will be
717 * cleared starting with 'StartNum' up to (and including) the
718 * Exact Match address number of 'StopNum'.
719 *
720 * Returns:
721 * nothing
722 */
723void SkXmClrExactAddr(
724SK_AC *pAC, /* adapter context */
725SK_IOC IoC, /* IO context */
726int Port, /* Port Index (MAC_1 + n) */
727int StartNum, /* Begin with this Address Register Index (0..15) */
728int StopNum) /* Stop after finished with this Register Idx (0..15) */
729{
730 int i;
731 SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
732
733 if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
734 StartNum > StopNum) {
735
736 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
737 return;
738 }
739
740 for (i = StartNum; i <= StopNum; i++) {
741 XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
742 }
743} /* SkXmClrExactAddr */
744#endif /* GENESIS */
745
746
747/******************************************************************************
748 *
749 * SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
750 *
751 * Description:
752 * Flush the transmit FIFO of the MAC specified by the index 'Port'
753 *
754 * Returns:
755 * nothing
756 */
757void SkMacFlushTxFifo(
758SK_AC *pAC, /* adapter context */
759SK_IOC IoC, /* IO context */
760int Port) /* Port Index (MAC_1 + n) */
761{
762#ifdef GENESIS
763 SK_U32 MdReg;
764
765 if (pAC->GIni.GIGenesis) {
766
767 XM_IN32(IoC, Port, XM_MODE, &MdReg);
768
769 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
770 }
771#endif /* GENESIS */
772
773#ifdef YUKON
774 if (pAC->GIni.GIYukon) {
775 /* no way to flush the FIFO we have to issue a reset */
776 /* TBD */
777 }
778#endif /* YUKON */
779
780} /* SkMacFlushTxFifo */
781
782
783/******************************************************************************
784 *
785 * SkMacFlushRxFifo() - Flush the MAC's receive FIFO
786 *
787 * Description:
788 * Flush the receive FIFO of the MAC specified by the index 'Port'
789 *
790 * Returns:
791 * nothing
792 */
793static void SkMacFlushRxFifo(
794SK_AC *pAC, /* adapter context */
795SK_IOC IoC, /* IO context */
796int Port) /* Port Index (MAC_1 + n) */
797{
798#ifdef GENESIS
799 SK_U32 MdReg;
800
801 if (pAC->GIni.GIGenesis) {
802
803 XM_IN32(IoC, Port, XM_MODE, &MdReg);
804
805 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
806 }
807#endif /* GENESIS */
808
809#ifdef YUKON
810 if (pAC->GIni.GIYukon) {
811 /* no way to flush the FIFO we have to issue a reset */
812 /* TBD */
813 }
814#endif /* YUKON */
815
816} /* SkMacFlushRxFifo */
817
818
819#ifdef GENESIS
820/******************************************************************************
821 *
822 * SkXmSoftRst() - Do a XMAC software reset
823 *
824 * Description:
825 * The PHY registers should not be destroyed during this
826 * kind of software reset. Therefore the XMAC Software Reset
827 * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
828 *
829 * The software reset is done by
830 * - disabling the Rx and Tx state machine,
831 * - resetting the statistics module,
832 * - clear all other significant XMAC Mode,
833 * Command, and Control Registers
834 * - clearing the Hash Register and the
835 * Exact Match Address registers, and
836 * - flushing the XMAC's Rx and Tx FIFOs.
837 *
838 * Note:
839 * Another requirement when stopping the XMAC is to
840 * avoid sending corrupted frames on the network.
841 * Disabling the Tx state machine will NOT interrupt
842 * the currently transmitted frame. But we must take care
843 * that the Tx FIFO is cleared AFTER the current frame
844 * is complete sent to the network.
845 *
846 * It takes about 12ns to send a frame with 1538 bytes.
847 * One PCI clock goes at least 15ns (66MHz). Therefore
848 * after reading XM_GP_PORT back, we are sure that the
849 * transmitter is disabled AND idle. And this means
850 * we may flush the transmit FIFO now.
851 *
852 * Returns:
853 * nothing
854 */
855static void SkXmSoftRst(
856SK_AC *pAC, /* adapter context */
857SK_IOC IoC, /* IO context */
858int Port) /* Port Index (MAC_1 + n) */
859{
860 SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
861
862 /* reset the statistics module */
863 XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
864
865 /* disable all XMAC IRQs */
866 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
867
868 XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */
869
870 XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */
871 XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */
872
873 /* disable all PHY IRQs */
874 switch (pAC->GIni.GP[Port].PhyType) {
875 case SK_PHY_BCOM:
876 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
877 break;
878#ifdef OTHER_PHY
879 case SK_PHY_LONE:
880 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
881 break;
882 case SK_PHY_NAT:
883 /* todo: National
884 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
885 break;
886#endif /* OTHER_PHY */
887 }
888
889 /* clear the Hash Register */
890 XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
891
892 /* clear the Exact Match Address registers */
893 SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
894
895 /* clear the Source Check Address registers */
896 XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
897
898} /* SkXmSoftRst */
899
900
901/******************************************************************************
902 *
903 * SkXmHardRst() - Do a XMAC hardware reset
904 *
905 * Description:
906 * The XMAC of the specified 'Port' and all connected devices
907 * (PHY and SERDES) will receive a reset signal on its *Reset pins.
908 * External PHYs must be reset by clearing a bit in the GPIO register
909 * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
910 *
911 * ATTENTION:
912 * It is absolutely necessary to reset the SW_RST Bit first
913 * before calling this function.
914 *
915 * Returns:
916 * nothing
917 */
918static void SkXmHardRst(
919SK_AC *pAC, /* adapter context */
920SK_IOC IoC, /* IO context */
921int Port) /* Port Index (MAC_1 + n) */
922{
923 SK_U32 Reg;
924 int i;
925 int TOut;
926 SK_U16 Word;
927
928 for (i = 0; i < 4; i++) {
929 /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
930 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
931
932 TOut = 0;
933 do {
934 if (TOut++ > 10000) {
935 /*
936 * Adapter seems to be in RESET state.
937 * Registers cannot be written.
938 */
939 return;
940 }
941
942 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
943
944 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
945
946 } while ((Word & MFF_SET_MAC_RST) == 0);
947 }
948
949 /* For external PHYs there must be special handling */
950 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
951
952 SK_IN32(IoC, B2_GP_IO, &Reg);
953
954 if (Port == 0) {
955 Reg |= GP_DIR_0; /* set to output */
956 Reg &= ~GP_IO_0; /* set PHY reset (active low) */
957 }
958 else {
959 Reg |= GP_DIR_2; /* set to output */
960 Reg &= ~GP_IO_2; /* set PHY reset (active low) */
961 }
962 /* reset external PHY */
963 SK_OUT32(IoC, B2_GP_IO, Reg);
964
965 /* short delay */
966 SK_IN32(IoC, B2_GP_IO, &Reg);
967 }
968} /* SkXmHardRst */
969
970
971/******************************************************************************
972 *
973 * SkXmClearRst() - Release the PHY & XMAC reset
974 *
975 * Description:
976 *
977 * Returns:
978 * nothing
979 */
980static void SkXmClearRst(
981SK_AC *pAC, /* adapter context */
982SK_IOC IoC, /* IO context */
983int Port) /* Port Index (MAC_1 + n) */
984{
985 SK_U32 DWord;
986
987 /* clear HW reset */
988 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
989
990 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
991
992 SK_IN32(IoC, B2_GP_IO, &DWord);
993
994 if (Port == 0) {
995 DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
996 }
997 else {
998 DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
999 }
1000 /* Clear PHY reset */
1001 SK_OUT32(IoC, B2_GP_IO, DWord);
1002
1003 /* Enable GMII interface */
1004 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
1005 }
1006} /* SkXmClearRst */
1007#endif /* GENESIS */
1008
1009
1010#ifdef YUKON
1011/******************************************************************************
1012 *
1013 * SkGmSoftRst() - Do a GMAC software reset
1014 *
1015 * Description:
1016 * The GPHY registers should not be destroyed during this
1017 * kind of software reset.
1018 *
1019 * Returns:
1020 * nothing
1021 */
1022static void SkGmSoftRst(
1023SK_AC *pAC, /* adapter context */
1024SK_IOC IoC, /* IO context */
1025int Port) /* Port Index (MAC_1 + n) */
1026{
1027 SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
1028 SK_U16 RxCtrl;
1029
1030 /* reset the statistics module */
1031
1032 /* disable all GMAC IRQs */
1033 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
1034
1035 /* disable all PHY IRQs */
1036 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
1037
1038 /* clear the Hash Register */
1039 GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
1040
1041 /* Enable Unicast and Multicast filtering */
1042 GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
1043
1044 GM_OUT16(IoC, Port, GM_RX_CTRL,
1045 (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
1046
1047} /* SkGmSoftRst */
1048
1049
1050/******************************************************************************
1051 *
1052 * SkGmHardRst() - Do a GMAC hardware reset
1053 *
1054 * Description:
1055 *
1056 * Returns:
1057 * nothing
1058 */
1059static void SkGmHardRst(
1060SK_AC *pAC, /* adapter context */
1061SK_IOC IoC, /* IO context */
1062int Port) /* Port Index (MAC_1 + n) */
1063{
1064 SK_U32 DWord;
1065
1066 /* WA code for COMA mode */
1067 if (pAC->GIni.GIYukonLite &&
1068 pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
1069
1070 SK_IN32(IoC, B2_GP_IO, &DWord);
1071
1072 DWord |= (GP_DIR_9 | GP_IO_9);
1073
1074 /* set PHY reset */
1075 SK_OUT32(IoC, B2_GP_IO, DWord);
1076 }
1077
1078 /* set GPHY Control reset */
1079 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
1080
1081 /* set GMAC Control reset */
1082 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1083
1084} /* SkGmHardRst */
1085
1086
1087/******************************************************************************
1088 *
1089 * SkGmClearRst() - Release the GPHY & GMAC reset
1090 *
1091 * Description:
1092 *
1093 * Returns:
1094 * nothing
1095 */
1096static void SkGmClearRst(
1097SK_AC *pAC, /* adapter context */
1098SK_IOC IoC, /* IO context */
1099int Port) /* Port Index (MAC_1 + n) */
1100{
1101 SK_U32 DWord;
1102
1103#ifdef XXX
1104 /* clear GMAC Control reset */
1105 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
1106
1107 /* set GMAC Control reset */
1108 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1109#endif /* XXX */
1110
1111 /* WA code for COMA mode */
1112 if (pAC->GIni.GIYukonLite &&
1113 pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
1114
1115 SK_IN32(IoC, B2_GP_IO, &DWord);
1116
1117 DWord |= GP_DIR_9; /* set to output */
1118 DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
1119
1120 /* clear PHY reset */
1121 SK_OUT32(IoC, B2_GP_IO, DWord);
1122 }
1123
1124 /* set HWCFG_MODE */
1125 DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
1126 GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
1127 (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
1128 GPC_HWCFG_GMII_FIB);
1129
1130 /* set GPHY Control reset */
1131 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
1132
1133 /* release GPHY Control reset */
1134 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
1135
1136#ifdef VCPU
1137 VCpuWait(9000);
1138#endif /* VCPU */
1139
1140 /* clear GMAC Control reset */
1141 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
1142
1143#ifdef VCPU
1144 VCpuWait(2000);
1145
1146 SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
1147
1148 SK_IN32(IoC, B0_ISRC, &DWord);
1149#endif /* VCPU */
1150
1151} /* SkGmClearRst */
1152#endif /* YUKON */
1153
1154
1155/******************************************************************************
1156 *
1157 * SkMacSoftRst() - Do a MAC software reset
1158 *
1159 * Description: calls a MAC software reset routine dep. on board type
1160 *
1161 * Returns:
1162 * nothing
1163 */
1164void SkMacSoftRst(
1165SK_AC *pAC, /* adapter context */
1166SK_IOC IoC, /* IO context */
1167int Port) /* Port Index (MAC_1 + n) */
1168{
1169 SK_GEPORT *pPrt;
1170
1171 pPrt = &pAC->GIni.GP[Port];
1172
1173 /* disable receiver and transmitter */
1174 SkMacRxTxDisable(pAC, IoC, Port);
1175
1176#ifdef GENESIS
1177 if (pAC->GIni.GIGenesis) {
1178
1179 SkXmSoftRst(pAC, IoC, Port);
1180 }
1181#endif /* GENESIS */
1182
1183#ifdef YUKON
1184 if (pAC->GIni.GIYukon) {
1185
1186 SkGmSoftRst(pAC, IoC, Port);
1187 }
1188#endif /* YUKON */
1189
1190 /* flush the MAC's Rx and Tx FIFOs */
1191 SkMacFlushTxFifo(pAC, IoC, Port);
1192
1193 SkMacFlushRxFifo(pAC, IoC, Port);
1194
1195 pPrt->PState = SK_PRT_STOP;
1196
1197} /* SkMacSoftRst */
1198
1199
1200/******************************************************************************
1201 *
1202 * SkMacHardRst() - Do a MAC hardware reset
1203 *
1204 * Description: calls a MAC hardware reset routine dep. on board type
1205 *
1206 * Returns:
1207 * nothing
1208 */
1209void SkMacHardRst(
1210SK_AC *pAC, /* adapter context */
1211SK_IOC IoC, /* IO context */
1212int Port) /* Port Index (MAC_1 + n) */
1213{
1214
1215#ifdef GENESIS
1216 if (pAC->GIni.GIGenesis) {
1217
1218 SkXmHardRst(pAC, IoC, Port);
1219 }
1220#endif /* GENESIS */
1221
1222#ifdef YUKON
1223 if (pAC->GIni.GIYukon) {
1224
1225 SkGmHardRst(pAC, IoC, Port);
1226 }
1227#endif /* YUKON */
1228
1229 pAC->GIni.GP[Port].PState = SK_PRT_RESET;
1230
1231} /* SkMacHardRst */
1232
1233
1234#ifdef GENESIS
1235/******************************************************************************
1236 *
1237 * SkXmInitMac() - Initialize the XMAC II
1238 *
1239 * Description:
1240 * Initialize the XMAC of the specified port.
1241 * The XMAC must be reset or stopped before calling this function.
1242 *
1243 * Note:
1244 * The XMAC's Rx and Tx state machine is still disabled when returning.
1245 *
1246 * Returns:
1247 * nothing
1248 */
1249void SkXmInitMac(
1250SK_AC *pAC, /* adapter context */
1251SK_IOC IoC, /* IO context */
1252int Port) /* Port Index (MAC_1 + n) */
1253{
1254 SK_GEPORT *pPrt;
1255 int i;
1256 SK_U16 SWord;
1257
1258 pPrt = &pAC->GIni.GP[Port];
1259
1260 if (pPrt->PState == SK_PRT_STOP) {
1261 /* Port State: SK_PRT_STOP */
1262 /* Verify that the reset bit is cleared */
1263 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
1264
1265 if ((SWord & MFF_SET_MAC_RST) != 0) {
1266 /* PState does not match HW state */
1267 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1268 /* Correct it */
1269 pPrt->PState = SK_PRT_RESET;
1270 }
1271 }
1272
1273 if (pPrt->PState == SK_PRT_RESET) {
1274
1275 SkXmClearRst(pAC, IoC, Port);
1276
1277 if (pPrt->PhyType != SK_PHY_XMAC) {
1278 /* read Id from external PHY (all have the same address) */
1279 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
1280
1281 /*
1282 * Optimize MDIO transfer by suppressing preamble.
1283 * Must be done AFTER first access to BCOM chip.
1284 */
1285 XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
1286
1287 XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
1288
1289 if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
1290 /*
1291 * Workaround BCOM Errata for the C0 type.
1292 * Write magic patterns to reserved registers.
1293 */
1294 i = 0;
1295 while (BcomRegC0Hack[i].PhyReg != 0) {
1296 SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
1297 BcomRegC0Hack[i].PhyVal);
1298 i++;
1299 }
1300 }
1301 else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
1302 /*
1303 * Workaround BCOM Errata for the A1 type.
1304 * Write magic patterns to reserved registers.
1305 */
1306 i = 0;
1307 while (BcomRegA1Hack[i].PhyReg != 0) {
1308 SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
1309 BcomRegA1Hack[i].PhyVal);
1310 i++;
1311 }
1312 }
1313
1314 /*
1315 * Workaround BCOM Errata (#10523) for all BCom PHYs.
1316 * Disable Power Management after reset.
1317 */
1318 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
1319
1320 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
1321 (SK_U16)(SWord | PHY_B_AC_DIS_PM));
1322
1323 /* PHY LED initialization is done in SkGeXmitLED() */
1324 }
1325
1326 /* Dummy read the Interrupt source register */
1327 XM_IN16(IoC, Port, XM_ISRC, &SWord);
1328
1329 /*
1330 * The auto-negotiation process starts immediately after
1331 * clearing the reset. The auto-negotiation process should be
1332 * started by the SIRQ, therefore stop it here immediately.
1333 */
1334 SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
1335
1336#ifdef TEST_ONLY
1337 /* temp. code: enable signal detect */
1338 /* WARNING: do not override GMII setting above */
1339 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG);
1340#endif
1341 }
1342
1343 /*
1344 * configure the XMACs Station Address
1345 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
1346 * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
1347 */
1348 for (i = 0; i < 3; i++) {
1349 /*
1350 * The following 2 statements are together endianess
1351 * independent. Remember this when changing.
1352 */
1353 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1354
1355 XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
1356 }
1357
1358 /* Tx Inter Packet Gap (XM_TX_IPG): use default */
1359 /* Tx High Water Mark (XM_TX_HI_WM): use default */
1360 /* Tx Low Water Mark (XM_TX_LO_WM): use default */
1361 /* Host Request Threshold (XM_HT_THR): use default */
1362 /* Rx Request Threshold (XM_RX_THR): use default */
1363 /* Rx Low Water Mark (XM_RX_LO_WM): use default */
1364
1365 /* configure Rx High Water Mark (XM_RX_HI_WM) */
1366 XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
1367
1368 /* Configure Tx Request Threshold */
1369 SWord = SK_XM_THR_SL; /* for single port */
1370
1371 if (pAC->GIni.GIMacsFound > 1) {
1372 switch (pAC->GIni.GIPortUsage) {
1373 case SK_RED_LINK:
1374 SWord = SK_XM_THR_REDL; /* redundant link */
1375 break;
1376 case SK_MUL_LINK:
1377 SWord = SK_XM_THR_MULL; /* load balancing */
1378 break;
1379 case SK_JUMBO_LINK:
1380 SWord = SK_XM_THR_JUMBO; /* jumbo frames */
1381 break;
1382 default:
1383 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
1384 break;
1385 }
1386 }
1387 XM_OUT16(IoC, Port, XM_TX_THR, SWord);
1388
1389 /* setup register defaults for the Tx Command Register */
1390 XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
1391
1392 /* setup register defaults for the Rx Command Register */
1393 SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
1394
1395 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1396 SWord |= XM_RX_BIG_PK_OK;
1397 }
1398
1399 if (pPrt->PLinkMode == SK_LMODE_HALF) {
1400 /*
1401 * If in manual half duplex mode the other side might be in
1402 * full duplex mode, so ignore if a carrier extension is not seen
1403 * on frames received
1404 */
1405 SWord |= XM_RX_DIS_CEXT;
1406 }
1407
1408 XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
1409
1410 /*
1411 * setup register defaults for the Mode Register
1412 * - Don't strip error frames to avoid Store & Forward
1413 * on the Rx side.
1414 * - Enable 'Check Station Address' bit
1415 * - Enable 'Check Address Array' bit
1416 */
1417 XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
1418
1419 /*
1420 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
1421 * - Enable all bits excepting 'Octets Rx OK Low CntOv'
1422 * and 'Octets Rx OK Hi Cnt Ov'.
1423 */
1424 XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
1425
1426 /*
1427 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
1428 * - Enable all bits excepting 'Octets Tx OK Low CntOv'
1429 * and 'Octets Tx OK Hi Cnt Ov'.
1430 */
1431 XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
1432
1433 /*
1434 * Do NOT init XMAC interrupt mask here.
1435 * All interrupts remain disable until link comes up!
1436 */
1437
1438 /*
1439 * Any additional configuration changes may be done now.
1440 * The last action is to enable the Rx and Tx state machine.
1441 * This should be done after the auto-negotiation process
1442 * has been completed successfully.
1443 */
1444} /* SkXmInitMac */
1445#endif /* GENESIS */
1446
1447
1448#ifdef YUKON
1449/******************************************************************************
1450 *
1451 * SkGmInitMac() - Initialize the GMAC
1452 *
1453 * Description:
1454 * Initialize the GMAC of the specified port.
1455 * The GMAC must be reset or stopped before calling this function.
1456 *
1457 * Note:
1458 * The GMAC's Rx and Tx state machine is still disabled when returning.
1459 *
1460 * Returns:
1461 * nothing
1462 */
1463void SkGmInitMac(
1464SK_AC *pAC, /* adapter context */
1465SK_IOC IoC, /* IO context */
1466int Port) /* Port Index (MAC_1 + n) */
1467{
1468 SK_GEPORT *pPrt;
1469 int i;
1470 SK_U16 SWord;
1471 SK_U32 DWord;
1472
1473 pPrt = &pAC->GIni.GP[Port];
1474
1475 if (pPrt->PState == SK_PRT_STOP) {
1476 /* Port State: SK_PRT_STOP */
1477 /* Verify that the reset bit is cleared */
1478 SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
1479
1480 if ((DWord & GMC_RST_SET) != 0) {
1481 /* PState does not match HW state */
1482 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1483 /* Correct it */
1484 pPrt->PState = SK_PRT_RESET;
1485 }
1486 }
1487
1488 if (pPrt->PState == SK_PRT_RESET) {
1489
1490 SkGmHardRst(pAC, IoC, Port);
1491
1492 SkGmClearRst(pAC, IoC, Port);
1493
1494 /* Auto-negotiation ? */
1495 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1496 /* Auto-negotiation disabled */
1497
1498 /* get General Purpose Control */
1499 GM_IN16(IoC, Port, GM_GP_CTRL, &SWord);
1500
1501 /* disable auto-update for speed, duplex and flow-control */
1502 SWord |= GM_GPCR_AU_ALL_DIS;
1503
1504 /* setup General Purpose Control Register */
1505 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1506
1507 SWord = GM_GPCR_AU_ALL_DIS;
1508 }
1509 else {
1510 SWord = 0;
1511 }
1512
1513 /* speed settings */
1514 switch (pPrt->PLinkSpeed) {
1515 case SK_LSPEED_AUTO:
1516 case SK_LSPEED_1000MBPS:
1517 SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
1518 break;
1519 case SK_LSPEED_100MBPS:
1520 SWord |= GM_GPCR_SPEED_100;
1521 break;
1522 case SK_LSPEED_10MBPS:
1523 break;
1524 }
1525
1526 /* duplex settings */
1527 if (pPrt->PLinkMode != SK_LMODE_HALF) {
1528 /* set full duplex */
1529 SWord |= GM_GPCR_DUP_FULL;
1530 }
1531
1532 /* flow-control settings */
1533 switch (pPrt->PFlowCtrlMode) {
1534 case SK_FLOW_MODE_NONE:
1535 /* set Pause Off */
1536 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
1537 /* disable Tx & Rx flow-control */
1538 SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1539 break;
1540 case SK_FLOW_MODE_LOC_SEND:
1541 /* disable Rx flow-control */
1542 SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1543 break;
1544 case SK_FLOW_MODE_SYMMETRIC:
1545 case SK_FLOW_MODE_SYM_OR_REM:
1546 /* enable Tx & Rx flow-control */
1547 break;
1548 }
1549
1550 /* setup General Purpose Control Register */
1551 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1552
1553 /* dummy read the Interrupt Source Register */
1554 SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
1555
1556#ifndef VCPU
1557 /* read Id from PHY */
1558 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
1559
1560 SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
1561#endif /* VCPU */
1562 }
1563
1564 (void)SkGmResetCounter(pAC, IoC, Port);
1565
1566 /* setup Transmit Control Register */
1567 GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
1568
1569 /* setup Receive Control Register */
1570 GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
1571 GM_RXCR_CRC_DIS);
1572
1573 /* setup Transmit Flow Control Register */
1574 GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
1575
1576 /* setup Transmit Parameter Register */
1577#ifdef VCPU
1578 GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
1579#endif /* VCPU */
1580
1581 SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
1582 TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
1583 TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
1584
1585 GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
1586
1587 /* configure the Serial Mode Register */
1588#ifdef VCPU
1589 GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
1590#endif /* VCPU */
1591
1592 SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
1593
1594 if (pPrt->PMacLimit4) {
1595 /* reset of collision counter after 4 consecutive collisions */
1596 SWord |= GM_SMOD_LIMIT_4;
1597 }
1598
1599 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1600 /* enable jumbo mode (Max. Frame Length = 9018) */
1601 SWord |= GM_SMOD_JUMBO_ENA;
1602 }
1603
1604 GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
1605
1606 /*
1607 * configure the GMACs Station Addresses
1608 * in PROM you can find our addresses at:
1609 * B2_MAC_1 = xx xx xx xx xx x0 virtual address
1610 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
1611 * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
1612 */
1613
1614 for (i = 0; i < 3; i++) {
1615 /*
1616 * The following 2 statements are together endianess
1617 * independent. Remember this when changing.
1618 */
1619 /* physical address: will be used for pause frames */
1620 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1621
1622#ifdef WA_DEV_16
1623 /* WA for deviation #16 */
1624 if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) {
1625 /* swap the address bytes */
1626 SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
1627
1628 /* write to register in reversed order */
1629 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
1630 }
1631 else {
1632 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1633 }
1634#else
1635 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1636#endif /* WA_DEV_16 */
1637
1638 /* virtual address: will be used for data */
1639 SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
1640
1641 GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
1642
1643 /* reset Multicast filtering Hash registers 1-3 */
1644 GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
1645 }
1646
1647 /* reset Multicast filtering Hash register 4 */
1648 GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
1649
1650 /* enable interrupt mask for counter overflows */
1651 GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
1652 GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
1653 GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
1654
1655#if defined(SK_DIAG) || defined(DEBUG)
1656 /* read General Purpose Status */
1657 GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
1658
1659 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1660 ("MAC Stat Reg.=0x%04X\n", SWord));
1661#endif /* SK_DIAG || DEBUG */
1662
1663#ifdef SK_DIAG
1664 c_print("MAC Stat Reg=0x%04X\n", SWord);
1665#endif /* SK_DIAG */
1666
1667} /* SkGmInitMac */
1668#endif /* YUKON */
1669
1670
1671#ifdef GENESIS
1672/******************************************************************************
1673 *
1674 * SkXmInitDupMd() - Initialize the XMACs Duplex Mode
1675 *
1676 * Description:
1677 * This function initializes the XMACs Duplex Mode.
1678 * It should be called after successfully finishing
1679 * the Auto-negotiation Process
1680 *
1681 * Returns:
1682 * nothing
1683 */
1684static void SkXmInitDupMd(
1685SK_AC *pAC, /* adapter context */
1686SK_IOC IoC, /* IO context */
1687int Port) /* Port Index (MAC_1 + n) */
1688{
1689 switch (pAC->GIni.GP[Port].PLinkModeStatus) {
1690 case SK_LMODE_STAT_AUTOHALF:
1691 case SK_LMODE_STAT_HALF:
1692 /* Configuration Actions for Half Duplex Mode */
1693 /*
1694 * XM_BURST = default value. We are probable not quick
1695 * enough at the 'XMAC' bus to burst 8kB.
1696 * The XMAC stops bursting if no transmit frames
1697 * are available or the burst limit is exceeded.
1698 */
1699 /* XM_TX_RT_LIM = default value (15) */
1700 /* XM_TX_STIME = default value (0xff = 4096 bit times) */
1701 break;
1702 case SK_LMODE_STAT_AUTOFULL:
1703 case SK_LMODE_STAT_FULL:
1704 /* Configuration Actions for Full Duplex Mode */
1705 /*
1706 * The duplex mode is configured by the PHY,
1707 * therefore it seems to be that there is nothing
1708 * to do here.
1709 */
1710 break;
1711 case SK_LMODE_STAT_UNKNOWN:
1712 default:
1713 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
1714 break;
1715 }
1716} /* SkXmInitDupMd */
1717
1718
1719/******************************************************************************
1720 *
1721 * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
1722 *
1723 * Description:
1724 * This function initializes the Pause Mode which should
1725 * be used for this port.
1726 * It should be called after successfully finishing
1727 * the Auto-negotiation Process
1728 *
1729 * Returns:
1730 * nothing
1731 */
1732static void SkXmInitPauseMd(
1733SK_AC *pAC, /* adapter context */
1734SK_IOC IoC, /* IO context */
1735int Port) /* Port Index (MAC_1 + n) */
1736{
1737 SK_GEPORT *pPrt;
1738 SK_U32 DWord;
1739 SK_U16 Word;
1740
1741 pPrt = &pAC->GIni.GP[Port];
1742
1743 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
1744
1745 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
1746 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1747
1748 /* Disable Pause Frame Reception */
1749 Word |= XM_MMU_IGN_PF;
1750 }
1751 else {
1752 /*
1753 * enabling pause frame reception is required for 1000BT
1754 * because the XMAC is not reset if the link is going down
1755 */
1756 /* Enable Pause Frame Reception */
1757 Word &= ~XM_MMU_IGN_PF;
1758 }
1759
1760 XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
1761
1762 XM_IN32(IoC, Port, XM_MODE, &DWord);
1763
1764 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
1765 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1766
1767 /*
1768 * Configure Pause Frame Generation
1769 * Use internal and external Pause Frame Generation.
1770 * Sending pause frames is edge triggered.
1771 * Send a Pause frame with the maximum pause time if
1772 * internal oder external FIFO full condition occurs.
1773 * Send a zero pause time frame to re-start transmission.
1774 */
1775
1776 /* XM_PAUSE_DA = '010000C28001' (default) */
1777
1778 /* XM_MAC_PTIME = 0xffff (maximum) */
1779 /* remember this value is defined in big endian (!) */
1780 XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
1781
1782 /* Set Pause Mode in Mode Register */
1783 DWord |= XM_PAUSE_MODE;
1784
1785 /* Set Pause Mode in MAC Rx FIFO */
1786 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
1787 }
1788 else {
1789 /*
1790 * disable pause frame generation is required for 1000BT
1791 * because the XMAC is not reset if the link is going down
1792 */
1793 /* Disable Pause Mode in Mode Register */
1794 DWord &= ~XM_PAUSE_MODE;
1795
1796 /* Disable Pause Mode in MAC Rx FIFO */
1797 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
1798 }
1799
1800 XM_OUT32(IoC, Port, XM_MODE, DWord);
1801} /* SkXmInitPauseMd*/
1802
1803
1804/******************************************************************************
1805 *
1806 * SkXmInitPhyXmac() - Initialize the XMAC Phy registers
1807 *
1808 * Description: initializes all the XMACs Phy registers
1809 *
1810 * Note:
1811 *
1812 * Returns:
1813 * nothing
1814 */
1815static void SkXmInitPhyXmac(
1816SK_AC *pAC, /* adapter context */
1817SK_IOC IoC, /* IO context */
1818int Port, /* Port Index (MAC_1 + n) */
1819SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1820{
1821 SK_GEPORT *pPrt;
1822 SK_U16 Ctrl;
1823
1824 pPrt = &pAC->GIni.GP[Port];
1825 Ctrl = 0;
1826
1827 /* Auto-negotiation ? */
1828 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1829 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1830 ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
1831 /* Set DuplexMode in Config register */
1832 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1833 Ctrl |= PHY_CT_DUP_MD;
1834 }
1835
1836 /*
1837 * Do NOT enable Auto-negotiation here. This would hold
1838 * the link down because no IDLEs are transmitted
1839 */
1840 }
1841 else {
1842 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1843 ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
1844 /* Set Auto-negotiation advertisement */
1845
1846 /* Set Full/half duplex capabilities */
1847 switch (pPrt->PLinkMode) {
1848 case SK_LMODE_AUTOHALF:
1849 Ctrl |= PHY_X_AN_HD;
1850 break;
1851 case SK_LMODE_AUTOFULL:
1852 Ctrl |= PHY_X_AN_FD;
1853 break;
1854 case SK_LMODE_AUTOBOTH:
1855 Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
1856 break;
1857 default:
1858 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
1859 SKERR_HWI_E015MSG);
1860 }
1861
1862 /* Set Flow-control capabilities */
1863 switch (pPrt->PFlowCtrlMode) {
1864 case SK_FLOW_MODE_NONE:
1865 Ctrl |= PHY_X_P_NO_PAUSE;
1866 break;
1867 case SK_FLOW_MODE_LOC_SEND:
1868 Ctrl |= PHY_X_P_ASYM_MD;
1869 break;
1870 case SK_FLOW_MODE_SYMMETRIC:
1871 Ctrl |= PHY_X_P_SYM_MD;
1872 break;
1873 case SK_FLOW_MODE_SYM_OR_REM:
1874 Ctrl |= PHY_X_P_BOTH_MD;
1875 break;
1876 default:
1877 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
1878 SKERR_HWI_E016MSG);
1879 }
1880
1881 /* Write AutoNeg Advertisement Register */
1882 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
1883
1884 /* Restart Auto-negotiation */
1885 Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
1886 }
1887
1888 if (DoLoop) {
1889 /* Set the Phy Loopback bit, too */
1890 Ctrl |= PHY_CT_LOOP;
1891 }
1892
1893 /* Write to the Phy control register */
1894 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
1895} /* SkXmInitPhyXmac */
1896
1897
1898/******************************************************************************
1899 *
1900 * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
1901 *
1902 * Description: initializes all the Broadcom Phy registers
1903 *
1904 * Note:
1905 *
1906 * Returns:
1907 * nothing
1908 */
1909static void SkXmInitPhyBcom(
1910SK_AC *pAC, /* adapter context */
1911SK_IOC IoC, /* IO context */
1912int Port, /* Port Index (MAC_1 + n) */
1913SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1914{
1915 SK_GEPORT *pPrt;
1916 SK_U16 Ctrl1;
1917 SK_U16 Ctrl2;
1918 SK_U16 Ctrl3;
1919 SK_U16 Ctrl4;
1920 SK_U16 Ctrl5;
1921
1922 Ctrl1 = PHY_CT_SP1000;
1923 Ctrl2 = 0;
1924 Ctrl3 = PHY_SEL_TYPE;
1925 Ctrl4 = PHY_B_PEC_EN_LTR;
1926 Ctrl5 = PHY_B_AC_TX_TST;
1927
1928 pPrt = &pAC->GIni.GP[Port];
1929
1930 /* manually Master/Slave ? */
1931 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
1932 Ctrl2 |= PHY_B_1000C_MSE;
1933
1934 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
1935 Ctrl2 |= PHY_B_1000C_MSC;
1936 }
1937 }
1938 /* Auto-negotiation ? */
1939 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1940 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1941 ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
1942 /* Set DuplexMode in Config register */
1943 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1944 Ctrl1 |= PHY_CT_DUP_MD;
1945 }
1946
1947 /* Determine Master/Slave manually if not already done */
1948 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
1949 Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
1950 }
1951
1952 /*
1953 * Do NOT enable Auto-negotiation here. This would hold
1954 * the link down because no IDLES are transmitted
1955 */
1956 }
1957 else {
1958 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1959 ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
1960 /* Set Auto-negotiation advertisement */
1961
1962 /*
1963 * Workaround BCOM Errata #1 for the C5 type.
1964 * 1000Base-T Link Acquisition Failure in Slave Mode
1965 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
1966 */
1967 Ctrl2 |= PHY_B_1000C_RD;
1968
1969 /* Set Full/half duplex capabilities */
1970 switch (pPrt->PLinkMode) {
1971 case SK_LMODE_AUTOHALF:
1972 Ctrl2 |= PHY_B_1000C_AHD;
1973 break;
1974 case SK_LMODE_AUTOFULL:
1975 Ctrl2 |= PHY_B_1000C_AFD;
1976 break;
1977 case SK_LMODE_AUTOBOTH:
1978 Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
1979 break;
1980 default:
1981 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
1982 SKERR_HWI_E015MSG);
1983 }
1984
1985 /* Set Flow-control capabilities */
1986 switch (pPrt->PFlowCtrlMode) {
1987 case SK_FLOW_MODE_NONE:
1988 Ctrl3 |= PHY_B_P_NO_PAUSE;
1989 break;
1990 case SK_FLOW_MODE_LOC_SEND:
1991 Ctrl3 |= PHY_B_P_ASYM_MD;
1992 break;
1993 case SK_FLOW_MODE_SYMMETRIC:
1994 Ctrl3 |= PHY_B_P_SYM_MD;
1995 break;
1996 case SK_FLOW_MODE_SYM_OR_REM:
1997 Ctrl3 |= PHY_B_P_BOTH_MD;
1998 break;
1999 default:
2000 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2001 SKERR_HWI_E016MSG);
2002 }
2003
2004 /* Restart Auto-negotiation */
2005 Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
2006 }
2007
2008 /* Initialize LED register here? */
2009 /* No. Please do it in SkDgXmitLed() (if required) and swap
2010 init order of LEDs and XMAC. (MAl) */
2011
2012 /* Write 1000Base-T Control Register */
2013 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
2014 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2015 ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2016
2017 /* Write AutoNeg Advertisement Register */
2018 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
2019 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2020 ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2021
2022 if (DoLoop) {
2023 /* Set the Phy Loopback bit, too */
2024 Ctrl1 |= PHY_CT_LOOP;
2025 }
2026
2027 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
2028 /* configure FIFO to high latency for transmission of ext. packets */
2029 Ctrl4 |= PHY_B_PEC_HIGH_LA;
2030
2031 /* configure reception of extended packets */
2032 Ctrl5 |= PHY_B_AC_LONG_PACK;
2033
2034 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
2035 }
2036
2037 /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
2038 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
2039
2040 /* Write to the Phy control register */
2041 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
2042 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2043 ("PHY Control Reg=0x%04X\n", Ctrl1));
2044} /* SkXmInitPhyBcom */
2045#endif /* GENESIS */
2046
2047#ifdef YUKON
2048/******************************************************************************
2049 *
2050 * SkGmInitPhyMarv() - Initialize the Marvell Phy registers
2051 *
2052 * Description: initializes all the Marvell Phy registers
2053 *
2054 * Note:
2055 *
2056 * Returns:
2057 * nothing
2058 */
2059static void SkGmInitPhyMarv(
2060SK_AC *pAC, /* adapter context */
2061SK_IOC IoC, /* IO context */
2062int Port, /* Port Index (MAC_1 + n) */
2063SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2064{
2065 SK_GEPORT *pPrt;
2066 SK_U16 PhyCtrl;
2067 SK_U16 C1000BaseT;
2068 SK_U16 AutoNegAdv;
2069 SK_U16 ExtPhyCtrl;
2070 SK_U16 LedCtrl;
2071 SK_BOOL AutoNeg;
2072#if defined(SK_DIAG) || defined(DEBUG)
2073 SK_U16 PhyStat;
2074 SK_U16 PhyStat1;
2075 SK_U16 PhySpecStat;
2076#endif /* SK_DIAG || DEBUG */
2077
2078 pPrt = &pAC->GIni.GP[Port];
2079
2080 /* Auto-negotiation ? */
2081 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2082 AutoNeg = SK_FALSE;
2083 }
2084 else {
2085 AutoNeg = SK_TRUE;
2086 }
2087
2088 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2089 ("InitPhyMarv: Port %d, auto-negotiation %s\n",
2090 Port, AutoNeg ? "ON" : "OFF"));
2091
2092#ifdef VCPU
2093 VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
2094 Port, DoLoop);
2095#else /* VCPU */
2096 if (DoLoop) {
2097 /* Set 'MAC Power up'-bit, set Manual MDI configuration */
2098 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2099 PHY_M_PC_MAC_POW_UP);
2100 }
2101 else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
2102 /* Read Ext. PHY Specific Control */
2103 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2104
2105 ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
2106 PHY_M_EC_MAC_S_MSK);
2107
2108 ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
2109 PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
2110
2111 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
2112 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2113 ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2114 }
2115
2116 /* Read PHY Control */
2117 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2118
2119 if (!AutoNeg) {
2120 /* Disable Auto-negotiation */
2121 PhyCtrl &= ~PHY_CT_ANE;
2122 }
2123
2124 PhyCtrl |= PHY_CT_RESET;
2125 /* Assert software reset */
2126 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2127#endif /* VCPU */
2128
2129 PhyCtrl = 0 /* PHY_CT_COL_TST */;
2130 C1000BaseT = 0;
2131 AutoNegAdv = PHY_SEL_TYPE;
2132
2133 /* manually Master/Slave ? */
2134 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2135 /* enable Manual Master/Slave */
2136 C1000BaseT |= PHY_M_1000C_MSE;
2137
2138 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2139 C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */
2140 }
2141 }
2142
2143 /* Auto-negotiation ? */
2144 if (!AutoNeg) {
2145
2146 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2147 /* Set Full Duplex Mode */
2148 PhyCtrl |= PHY_CT_DUP_MD;
2149 }
2150
2151 /* Set Master/Slave manually if not already done */
2152 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2153 C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */
2154 }
2155
2156 /* Set Speed */
2157 switch (pPrt->PLinkSpeed) {
2158 case SK_LSPEED_AUTO:
2159 case SK_LSPEED_1000MBPS:
2160 PhyCtrl |= PHY_CT_SP1000;
2161 break;
2162 case SK_LSPEED_100MBPS:
2163 PhyCtrl |= PHY_CT_SP100;
2164 break;
2165 case SK_LSPEED_10MBPS:
2166 break;
2167 default:
2168 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2169 SKERR_HWI_E019MSG);
2170 }
2171
2172 if (!DoLoop) {
2173 PhyCtrl |= PHY_CT_RESET;
2174 }
2175 }
2176 else {
2177 /* Set Auto-negotiation advertisement */
2178
2179 if (pAC->GIni.GICopperType) {
2180 /* Set Speed capabilities */
2181 switch (pPrt->PLinkSpeed) {
2182 case SK_LSPEED_AUTO:
2183 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2184 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2185 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2186 break;
2187 case SK_LSPEED_1000MBPS:
2188 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2189 break;
2190 case SK_LSPEED_100MBPS:
2191 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2192 /* advertise 10Base-T also */
2193 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2194 break;
2195 case SK_LSPEED_10MBPS:
2196 AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2197 break;
2198 default:
2199 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2200 SKERR_HWI_E019MSG);
2201 }
2202
2203 /* Set Full/half duplex capabilities */
2204 switch (pPrt->PLinkMode) {
2205 case SK_LMODE_AUTOHALF:
2206 C1000BaseT &= ~PHY_M_1000C_AFD;
2207 AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
2208 break;
2209 case SK_LMODE_AUTOFULL:
2210 C1000BaseT &= ~PHY_M_1000C_AHD;
2211 AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
2212 break;
2213 case SK_LMODE_AUTOBOTH:
2214 break;
2215 default:
2216 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2217 SKERR_HWI_E015MSG);
2218 }
2219
2220 /* Set Flow-control capabilities */
2221 switch (pPrt->PFlowCtrlMode) {
2222 case SK_FLOW_MODE_NONE:
2223 AutoNegAdv |= PHY_B_P_NO_PAUSE;
2224 break;
2225 case SK_FLOW_MODE_LOC_SEND:
2226 AutoNegAdv |= PHY_B_P_ASYM_MD;
2227 break;
2228 case SK_FLOW_MODE_SYMMETRIC:
2229 AutoNegAdv |= PHY_B_P_SYM_MD;
2230 break;
2231 case SK_FLOW_MODE_SYM_OR_REM:
2232 AutoNegAdv |= PHY_B_P_BOTH_MD;
2233 break;
2234 default:
2235 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2236 SKERR_HWI_E016MSG);
2237 }
2238 }
2239 else { /* special defines for FIBER (88E1011S only) */
2240
2241 /* Set Full/half duplex capabilities */
2242 switch (pPrt->PLinkMode) {
2243 case SK_LMODE_AUTOHALF:
2244 AutoNegAdv |= PHY_M_AN_1000X_AHD;
2245 break;
2246 case SK_LMODE_AUTOFULL:
2247 AutoNegAdv |= PHY_M_AN_1000X_AFD;
2248 break;
2249 case SK_LMODE_AUTOBOTH:
2250 AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
2251 break;
2252 default:
2253 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2254 SKERR_HWI_E015MSG);
2255 }
2256
2257 /* Set Flow-control capabilities */
2258 switch (pPrt->PFlowCtrlMode) {
2259 case SK_FLOW_MODE_NONE:
2260 AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
2261 break;
2262 case SK_FLOW_MODE_LOC_SEND:
2263 AutoNegAdv |= PHY_M_P_ASYM_MD_X;
2264 break;
2265 case SK_FLOW_MODE_SYMMETRIC:
2266 AutoNegAdv |= PHY_M_P_SYM_MD_X;
2267 break;
2268 case SK_FLOW_MODE_SYM_OR_REM:
2269 AutoNegAdv |= PHY_M_P_BOTH_MD_X;
2270 break;
2271 default:
2272 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2273 SKERR_HWI_E016MSG);
2274 }
2275 }
2276
2277 if (!DoLoop) {
2278 /* Restart Auto-negotiation */
2279 PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
2280 }
2281 }
2282
2283#ifdef VCPU
2284 /*
2285 * E-mail from Gu Lin (08-03-2002):
2286 */
2287
2288 /* Program PHY register 30 as 16'h0708 for simulation speed up */
2289 SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
2290
2291 VCpuWait(2000);
2292
2293#else /* VCPU */
2294
2295 /* Write 1000Base-T Control Register */
2296 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
2297 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2298 ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
2299
2300 /* Write AutoNeg Advertisement Register */
2301 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
2302 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2303 ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2304#endif /* VCPU */
2305
2306 if (DoLoop) {
2307 /* Set the PHY Loopback bit */
2308 PhyCtrl |= PHY_CT_LOOP;
2309
2310#ifdef XXX
2311 /* Program PHY register 16 as 16'h0400 to force link good */
2312 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
2313#endif /* XXX */
2314
2315#ifndef VCPU
2316 if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
2317 /* Write Ext. PHY Specific Control */
2318 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
2319 (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
2320 }
2321#endif /* VCPU */
2322 }
2323#ifdef TEST_ONLY
2324 else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
2325 /* Write PHY Specific Control */
2326 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2327 PHY_M_PC_EN_DET_MSK);
2328 }
2329#endif
2330
2331 /* Write to the PHY Control register */
2332 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2333 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2334 ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2335
2336#ifdef VCPU
2337 VCpuWait(2000);
2338#else
2339
2340 LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
2341
2342 if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
2343 LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
2344 }
2345
2346 if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
2347 LedCtrl |= PHY_M_LEDC_DP_CTRL;
2348 }
2349
2350 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
2351
2352 if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
2353 /* only in forced 100 Mbps mode */
2354 if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
2355
2356 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
2357 PHY_M_LED_MO_100(MO_LED_ON));
2358 }
2359 }
2360
2361#ifdef SK_DIAG
2362 c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
2363 c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
2364 c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
2365 c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
2366#endif /* SK_DIAG */
2367
2368#if defined(SK_DIAG) || defined(DEBUG)
2369 /* Read PHY Control */
2370 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2371 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2372 ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2373
2374 /* Read 1000Base-T Control Register */
2375 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
2376 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2377 ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
2378
2379 /* Read AutoNeg Advertisement Register */
2380 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
2381 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2382 ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2383
2384 /* Read Ext. PHY Specific Control */
2385 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2386 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2387 ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2388
2389 /* Read PHY Status */
2390 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
2391 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2392 ("PHY Stat Reg.=0x%04X\n", PhyStat));
2393 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
2394 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2395 ("PHY Stat Reg.=0x%04X\n", PhyStat1));
2396
2397 /* Read PHY Specific Status */
2398 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
2399 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2400 ("PHY Spec Stat=0x%04X\n", PhySpecStat));
2401#endif /* SK_DIAG || DEBUG */
2402
2403#ifdef SK_DIAG
2404 c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
2405 c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
2406 c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
2407 c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
2408 c_print("PHY Stat Reg=0x%04X\n", PhyStat);
2409 c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
2410 c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
2411#endif /* SK_DIAG */
2412
2413#endif /* VCPU */
2414
2415} /* SkGmInitPhyMarv */
2416#endif /* YUKON */
2417
2418
2419#ifdef OTHER_PHY
2420/******************************************************************************
2421 *
2422 * SkXmInitPhyLone() - Initialize the Level One Phy registers
2423 *
2424 * Description: initializes all the Level One Phy registers
2425 *
2426 * Note:
2427 *
2428 * Returns:
2429 * nothing
2430 */
2431static void SkXmInitPhyLone(
2432SK_AC *pAC, /* adapter context */
2433SK_IOC IoC, /* IO context */
2434int Port, /* Port Index (MAC_1 + n) */
2435SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2436{
2437 SK_GEPORT *pPrt;
2438 SK_U16 Ctrl1;
2439 SK_U16 Ctrl2;
2440 SK_U16 Ctrl3;
2441
2442 Ctrl1 = PHY_CT_SP1000;
2443 Ctrl2 = 0;
2444 Ctrl3 = PHY_SEL_TYPE;
2445
2446 pPrt = &pAC->GIni.GP[Port];
2447
2448 /* manually Master/Slave ? */
2449 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2450 Ctrl2 |= PHY_L_1000C_MSE;
2451
2452 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2453 Ctrl2 |= PHY_L_1000C_MSC;
2454 }
2455 }
2456 /* Auto-negotiation ? */
2457 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2458 /*
2459 * level one spec say: "1000 Mbps: manual mode not allowed"
2460 * but lets see what happens...
2461 */
2462 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2463 ("InitPhyLone: no auto-negotiation Port %d\n", Port));
2464 /* Set DuplexMode in Config register */
2465 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2466 Ctrl1 |= PHY_CT_DUP_MD;
2467 }
2468
2469 /* Determine Master/Slave manually if not already done */
2470 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2471 Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */
2472 }
2473
2474 /*
2475 * Do NOT enable Auto-negotiation here. This would hold
2476 * the link down because no IDLES are transmitted
2477 */
2478 }
2479 else {
2480 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2481 ("InitPhyLone: with auto-negotiation Port %d\n", Port));
2482 /* Set Auto-negotiation advertisement */
2483
2484 /* Set Full/half duplex capabilities */
2485 switch (pPrt->PLinkMode) {
2486 case SK_LMODE_AUTOHALF:
2487 Ctrl2 |= PHY_L_1000C_AHD;
2488 break;
2489 case SK_LMODE_AUTOFULL:
2490 Ctrl2 |= PHY_L_1000C_AFD;
2491 break;
2492 case SK_LMODE_AUTOBOTH:
2493 Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
2494 break;
2495 default:
2496 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2497 SKERR_HWI_E015MSG);
2498 }
2499
2500 /* Set Flow-control capabilities */
2501 switch (pPrt->PFlowCtrlMode) {
2502 case SK_FLOW_MODE_NONE:
2503 Ctrl3 |= PHY_L_P_NO_PAUSE;
2504 break;
2505 case SK_FLOW_MODE_LOC_SEND:
2506 Ctrl3 |= PHY_L_P_ASYM_MD;
2507 break;
2508 case SK_FLOW_MODE_SYMMETRIC:
2509 Ctrl3 |= PHY_L_P_SYM_MD;
2510 break;
2511 case SK_FLOW_MODE_SYM_OR_REM:
2512 Ctrl3 |= PHY_L_P_BOTH_MD;
2513 break;
2514 default:
2515 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2516 SKERR_HWI_E016MSG);
2517 }
2518
2519 /* Restart Auto-negotiation */
2520 Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
2521 }
2522
2523 /* Write 1000Base-T Control Register */
2524 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
2525 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2526 ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2527
2528 /* Write AutoNeg Advertisement Register */
2529 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
2530 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2531 ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2532
2533 if (DoLoop) {
2534 /* Set the Phy Loopback bit, too */
2535 Ctrl1 |= PHY_CT_LOOP;
2536 }
2537
2538 /* Write to the Phy control register */
2539 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
2540 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2541 ("PHY Control Reg=0x%04X\n", Ctrl1));
2542} /* SkXmInitPhyLone */
2543
2544
2545/******************************************************************************
2546 *
2547 * SkXmInitPhyNat() - Initialize the National Phy registers
2548 *
2549 * Description: initializes all the National Phy registers
2550 *
2551 * Note:
2552 *
2553 * Returns:
2554 * nothing
2555 */
2556static void SkXmInitPhyNat(
2557SK_AC *pAC, /* adapter context */
2558SK_IOC IoC, /* IO context */
2559int Port, /* Port Index (MAC_1 + n) */
2560SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2561{
2562/* todo: National */
2563} /* SkXmInitPhyNat */
2564#endif /* OTHER_PHY */
2565
2566
2567/******************************************************************************
2568 *
2569 * SkMacInitPhy() - Initialize the PHY registers
2570 *
2571 * Description: calls the Init PHY routines dep. on board type
2572 *
2573 * Note:
2574 *
2575 * Returns:
2576 * nothing
2577 */
2578void SkMacInitPhy(
2579SK_AC *pAC, /* adapter context */
2580SK_IOC IoC, /* IO context */
2581int Port, /* Port Index (MAC_1 + n) */
2582SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2583{
2584 SK_GEPORT *pPrt;
2585
2586 pPrt = &pAC->GIni.GP[Port];
2587
2588#ifdef GENESIS
2589 if (pAC->GIni.GIGenesis) {
2590
2591 switch (pPrt->PhyType) {
2592 case SK_PHY_XMAC:
2593 SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
2594 break;
2595 case SK_PHY_BCOM:
2596 SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
2597 break;
2598#ifdef OTHER_PHY
2599 case SK_PHY_LONE:
2600 SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
2601 break;
2602 case SK_PHY_NAT:
2603 SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
2604 break;
2605#endif /* OTHER_PHY */
2606 }
2607 }
2608#endif /* GENESIS */
2609
2610#ifdef YUKON
2611 if (pAC->GIni.GIYukon) {
2612
2613 SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
2614 }
2615#endif /* YUKON */
2616
2617} /* SkMacInitPhy */
2618
2619
2620#ifdef GENESIS
2621/******************************************************************************
2622 *
2623 * SkXmAutoNegDoneXmac() - Auto-negotiation handling
2624 *
2625 * Description:
2626 * This function handles the auto-negotiation if the Done bit is set.
2627 *
2628 * Returns:
2629 * SK_AND_OK o.k.
2630 * SK_AND_DUP_CAP Duplex capability error happened
2631 * SK_AND_OTHER Other error happened
2632 */
2633static int SkXmAutoNegDoneXmac(
2634SK_AC *pAC, /* adapter context */
2635SK_IOC IoC, /* IO context */
2636int Port) /* Port Index (MAC_1 + n) */
2637{
2638 SK_GEPORT *pPrt;
2639 SK_U16 ResAb; /* Resolved Ability */
2640 SK_U16 LPAb; /* Link Partner Ability */
2641
2642 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2643 ("AutoNegDoneXmac, Port %d\n", Port));
2644
2645 pPrt = &pAC->GIni.GP[Port];
2646
2647 /* Get PHY parameters */
2648 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
2649 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
2650
2651 if ((LPAb & PHY_X_AN_RFB) != 0) {
2652 /* At least one of the remote fault bit is set */
2653 /* Error */
2654 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2655 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2656 pPrt->PAutoNegFail = SK_TRUE;
2657 return(SK_AND_OTHER);
2658 }
2659
2660 /* Check Duplex mismatch */
2661 if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
2662 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2663 }
2664 else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
2665 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2666 }
2667 else {
2668 /* Error */
2669 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2670 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
2671 pPrt->PAutoNegFail = SK_TRUE;
2672 return(SK_AND_DUP_CAP);
2673 }
2674
2675 /* Check PAUSE mismatch */
2676 /* We are NOT using chapter 4.23 of the Xaqti manual */
2677 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2678 if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
2679 pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
2680 (LPAb & PHY_X_P_SYM_MD) != 0) {
2681 /* Symmetric PAUSE */
2682 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2683 }
2684 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
2685 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
2686 /* Enable PAUSE receive, disable PAUSE transmit */
2687 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2688 }
2689 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
2690 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
2691 /* Disable PAUSE receive, enable PAUSE transmit */
2692 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2693 }
2694 else {
2695 /* PAUSE mismatch -> no PAUSE */
2696 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2697 }
2698 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2699
2700 return(SK_AND_OK);
2701} /* SkXmAutoNegDoneXmac */
2702
2703
2704/******************************************************************************
2705 *
2706 * SkXmAutoNegDoneBcom() - Auto-negotiation handling
2707 *
2708 * Description:
2709 * This function handles the auto-negotiation if the Done bit is set.
2710 *
2711 * Returns:
2712 * SK_AND_OK o.k.
2713 * SK_AND_DUP_CAP Duplex capability error happened
2714 * SK_AND_OTHER Other error happened
2715 */
2716static int SkXmAutoNegDoneBcom(
2717SK_AC *pAC, /* adapter context */
2718SK_IOC IoC, /* IO context */
2719int Port) /* Port Index (MAC_1 + n) */
2720{
2721 SK_GEPORT *pPrt;
2722 SK_U16 LPAb; /* Link Partner Ability */
2723 SK_U16 AuxStat; /* Auxiliary Status */
2724
2725#ifdef TEST_ONLY
272601-Sep-2000 RA;:;:
2727 SK_U16 ResAb; /* Resolved Ability */
2728#endif /* 0 */
2729
2730 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2731 ("AutoNegDoneBcom, Port %d\n", Port));
2732 pPrt = &pAC->GIni.GP[Port];
2733
2734 /* Get PHY parameters */
2735 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
2736#ifdef TEST_ONLY
273701-Sep-2000 RA;:;:
2738 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
2739#endif /* 0 */
2740
2741 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
2742
2743 if ((LPAb & PHY_B_AN_RF) != 0) {
2744 /* Remote fault bit is set: Error */
2745 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2746 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2747 pPrt->PAutoNegFail = SK_TRUE;
2748 return(SK_AND_OTHER);
2749 }
2750
2751 /* Check Duplex mismatch */
2752 if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
2753 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2754 }
2755 else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
2756 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2757 }
2758 else {
2759 /* Error */
2760 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2761 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
2762 pPrt->PAutoNegFail = SK_TRUE;
2763 return(SK_AND_DUP_CAP);
2764 }
2765
2766#ifdef TEST_ONLY
276701-Sep-2000 RA;:;:
2768 /* Check Master/Slave resolution */
2769 if ((ResAb & PHY_B_1000S_MSF) != 0) {
2770 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2771 ("Master/Slave Fault Port %d\n", Port));
2772 pPrt->PAutoNegFail = SK_TRUE;
2773 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2774 return(SK_AND_OTHER);
2775 }
2776
2777 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
2778 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
2779#endif /* 0 */
2780
2781 /* Check PAUSE mismatch ??? */
2782 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2783 if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
2784 /* Symmetric PAUSE */
2785 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2786 }
2787 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
2788 /* Enable PAUSE receive, disable PAUSE transmit */
2789 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2790 }
2791 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
2792 /* Disable PAUSE receive, enable PAUSE transmit */
2793 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2794 }
2795 else {
2796 /* PAUSE mismatch -> no PAUSE */
2797 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2798 }
2799 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2800
2801 return(SK_AND_OK);
2802} /* SkXmAutoNegDoneBcom */
2803#endif /* GENESIS */
2804
2805
2806#ifdef YUKON
2807/******************************************************************************
2808 *
2809 * SkGmAutoNegDoneMarv() - Auto-negotiation handling
2810 *
2811 * Description:
2812 * This function handles the auto-negotiation if the Done bit is set.
2813 *
2814 * Returns:
2815 * SK_AND_OK o.k.
2816 * SK_AND_DUP_CAP Duplex capability error happened
2817 * SK_AND_OTHER Other error happened
2818 */
2819static int SkGmAutoNegDoneMarv(
2820SK_AC *pAC, /* adapter context */
2821SK_IOC IoC, /* IO context */
2822int Port) /* Port Index (MAC_1 + n) */
2823{
2824 SK_GEPORT *pPrt;
2825 SK_U16 LPAb; /* Link Partner Ability */
2826 SK_U16 ResAb; /* Resolved Ability */
2827 SK_U16 AuxStat; /* Auxiliary Status */
2828
2829 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2830 ("AutoNegDoneMarv, Port %d\n", Port));
2831 pPrt = &pAC->GIni.GP[Port];
2832
2833 /* Get PHY parameters */
2834 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
2835 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2836 ("Link P.Abil.=0x%04X\n", LPAb));
2837
2838 if ((LPAb & PHY_M_AN_RF) != 0) {
2839 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2840 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2841 pPrt->PAutoNegFail = SK_TRUE;
2842 return(SK_AND_OTHER);
2843 }
2844
2845 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
2846
2847 /* Check Master/Slave resolution */
2848 if ((ResAb & PHY_B_1000S_MSF) != 0) {
2849 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2850 ("Master/Slave Fault Port %d\n", Port));
2851 pPrt->PAutoNegFail = SK_TRUE;
2852 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2853 return(SK_AND_OTHER);
2854 }
2855
2856 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
2857 (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
2858
2859 /* Read PHY Specific Status */
2860 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
2861
2862 /* Check Speed & Duplex resolved */
2863 if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
2864 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2865 ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
2866 pPrt->PAutoNegFail = SK_TRUE;
2867 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
2868 return(SK_AND_DUP_CAP);
2869 }
2870
2871 if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
2872 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2873 }
2874 else {
2875 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2876 }
2877
2878 /* Check PAUSE mismatch ??? */
2879 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2880 if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
2881 /* Symmetric PAUSE */
2882 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2883 }
2884 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
2885 /* Enable PAUSE receive, disable PAUSE transmit */
2886 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2887 }
2888 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
2889 /* Disable PAUSE receive, enable PAUSE transmit */
2890 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2891 }
2892 else {
2893 /* PAUSE mismatch -> no PAUSE */
2894 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2895 }
2896
2897 /* set used link speed */
2898 switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
2899 case (unsigned)PHY_M_PS_SPEED_1000:
2900 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2901 break;
2902 case PHY_M_PS_SPEED_100:
2903 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
2904 break;
2905 default:
2906 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
2907 }
2908
2909 return(SK_AND_OK);
2910} /* SkGmAutoNegDoneMarv */
2911#endif /* YUKON */
2912
2913
2914#ifdef OTHER_PHY
2915/******************************************************************************
2916 *
2917 * SkXmAutoNegDoneLone() - Auto-negotiation handling
2918 *
2919 * Description:
2920 * This function handles the auto-negotiation if the Done bit is set.
2921 *
2922 * Returns:
2923 * SK_AND_OK o.k.
2924 * SK_AND_DUP_CAP Duplex capability error happened
2925 * SK_AND_OTHER Other error happened
2926 */
2927static int SkXmAutoNegDoneLone(
2928SK_AC *pAC, /* adapter context */
2929SK_IOC IoC, /* IO context */
2930int Port) /* Port Index (MAC_1 + n) */
2931{
2932 SK_GEPORT *pPrt;
2933 SK_U16 ResAb; /* Resolved Ability */
2934 SK_U16 LPAb; /* Link Partner Ability */
2935 SK_U16 QuickStat; /* Auxiliary Status */
2936
2937 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2938 ("AutoNegDoneLone, Port %d\n", Port));
2939 pPrt = &pAC->GIni.GP[Port];
2940
2941 /* Get PHY parameters */
2942 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
2943 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
2944 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
2945
2946 if ((LPAb & PHY_L_AN_RF) != 0) {
2947 /* Remote fault bit is set */
2948 /* Error */
2949 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2950 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2951 pPrt->PAutoNegFail = SK_TRUE;
2952 return(SK_AND_OTHER);
2953 }
2954
2955 /* Check Duplex mismatch */
2956 if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
2957 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2958 }
2959 else {
2960 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2961 }
2962
2963 /* Check Master/Slave resolution */
2964 if ((ResAb & PHY_L_1000S_MSF) != 0) {
2965 /* Error */
2966 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2967 ("Master/Slave Fault Port %d\n", Port));
2968 pPrt->PAutoNegFail = SK_TRUE;
2969 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2970 return(SK_AND_OTHER);
2971 }
2972 else if (ResAb & PHY_L_1000S_MSR) {
2973 pPrt->PMSStatus = SK_MS_STAT_MASTER;
2974 }
2975 else {
2976 pPrt->PMSStatus = SK_MS_STAT_SLAVE;
2977 }
2978
2979 /* Check PAUSE mismatch */
2980 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2981 /* we must manually resolve the abilities here */
2982 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2983
2984 switch (pPrt->PFlowCtrlMode) {
2985 case SK_FLOW_MODE_NONE:
2986 /* default */
2987 break;
2988 case SK_FLOW_MODE_LOC_SEND:
2989 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
2990 (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
2991 /* Disable PAUSE receive, enable PAUSE transmit */
2992 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2993 }
2994 break;
2995 case SK_FLOW_MODE_SYMMETRIC:
2996 if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
2997 /* Symmetric PAUSE */
2998 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2999 }
3000 break;
3001 case SK_FLOW_MODE_SYM_OR_REM:
3002 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
3003 PHY_L_QS_AS_PAUSE) {
3004 /* Enable PAUSE receive, disable PAUSE transmit */
3005 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
3006 }
3007 else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
3008 /* Symmetric PAUSE */
3009 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
3010 }
3011 break;
3012 default:
3013 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
3014 SKERR_HWI_E016MSG);
3015 }
3016
3017 return(SK_AND_OK);
3018} /* SkXmAutoNegDoneLone */
3019
3020
3021/******************************************************************************
3022 *
3023 * SkXmAutoNegDoneNat() - Auto-negotiation handling
3024 *
3025 * Description:
3026 * This function handles the auto-negotiation if the Done bit is set.
3027 *
3028 * Returns:
3029 * SK_AND_OK o.k.
3030 * SK_AND_DUP_CAP Duplex capability error happened
3031 * SK_AND_OTHER Other error happened
3032 */
3033static int SkXmAutoNegDoneNat(
3034SK_AC *pAC, /* adapter context */
3035SK_IOC IoC, /* IO context */
3036int Port) /* Port Index (MAC_1 + n) */
3037{
3038/* todo: National */
3039 return(SK_AND_OK);
3040} /* SkXmAutoNegDoneNat */
3041#endif /* OTHER_PHY */
3042
3043
3044/******************************************************************************
3045 *
3046 * SkMacAutoNegDone() - Auto-negotiation handling
3047 *
3048 * Description: calls the auto-negotiation done routines dep. on board type
3049 *
3050 * Returns:
3051 * SK_AND_OK o.k.
3052 * SK_AND_DUP_CAP Duplex capability error happened
3053 * SK_AND_OTHER Other error happened
3054 */
3055int SkMacAutoNegDone(
3056SK_AC *pAC, /* adapter context */
3057SK_IOC IoC, /* IO context */
3058int Port) /* Port Index (MAC_1 + n) */
3059{
3060 SK_GEPORT *pPrt;
3061 int Rtv;
3062
3063 Rtv = SK_AND_OK;
3064
3065 pPrt = &pAC->GIni.GP[Port];
3066
3067#ifdef GENESIS
3068 if (pAC->GIni.GIGenesis) {
3069
3070 switch (pPrt->PhyType) {
3071
3072 case SK_PHY_XMAC:
3073 Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
3074 break;
3075 case SK_PHY_BCOM:
3076 Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
3077 break;
3078#ifdef OTHER_PHY
3079 case SK_PHY_LONE:
3080 Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
3081 break;
3082 case SK_PHY_NAT:
3083 Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
3084 break;
3085#endif /* OTHER_PHY */
3086 default:
3087 return(SK_AND_OTHER);
3088 }
3089 }
3090#endif /* GENESIS */
3091
3092#ifdef YUKON
3093 if (pAC->GIni.GIYukon) {
3094
3095 Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
3096 }
3097#endif /* YUKON */
3098
3099 if (Rtv != SK_AND_OK) {
3100 return(Rtv);
3101 }
3102
3103 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3104 ("AutoNeg done Port %d\n", Port));
3105
3106 /* We checked everything and may now enable the link */
3107 pPrt->PAutoNegFail = SK_FALSE;
3108
3109 SkMacRxTxEnable(pAC, IoC, Port);
3110
3111 return(SK_AND_OK);
3112} /* SkMacAutoNegDone */
3113
3114
3115/******************************************************************************
3116 *
3117 * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
3118 *
3119 * Description: enables Rx/Tx dep. on board type
3120 *
3121 * Returns:
3122 * 0 o.k.
3123 * != 0 Error happened
3124 */
3125int SkMacRxTxEnable(
3126SK_AC *pAC, /* adapter context */
3127SK_IOC IoC, /* IO context */
3128int Port) /* Port Index (MAC_1 + n) */
3129{
3130 SK_GEPORT *pPrt;
3131 SK_U16 Reg; /* 16-bit register value */
3132 SK_U16 IntMask; /* MAC interrupt mask */
3133#ifdef GENESIS
3134 SK_U16 SWord;
3135#endif
3136
3137 pPrt = &pAC->GIni.GP[Port];
3138
3139 if (!pPrt->PHWLinkUp) {
3140 /* The Hardware link is NOT up */
3141 return(0);
3142 }
3143
3144 if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
3145 pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
3146 pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
3147 pPrt->PAutoNegFail) {
3148 /* Auto-negotiation is not done or failed */
3149 return(0);
3150 }
3151
3152#ifdef GENESIS
3153 if (pAC->GIni.GIGenesis) {
3154 /* set Duplex Mode and Pause Mode */
3155 SkXmInitDupMd(pAC, IoC, Port);
3156
3157 SkXmInitPauseMd(pAC, IoC, Port);
3158
3159 /*
3160 * Initialize the Interrupt Mask Register. Default IRQs are...
3161 * - Link Asynchronous Event
3162 * - Link Partner requests config
3163 * - Auto Negotiation Done
3164 * - Rx Counter Event Overflow
3165 * - Tx Counter Event Overflow
3166 * - Transmit FIFO Underrun
3167 */
3168 IntMask = XM_DEF_MSK;
3169
3170#ifdef DEBUG
3171 /* add IRQ for Receive FIFO Overflow */
3172 IntMask &= ~XM_IS_RXF_OV;
3173#endif /* DEBUG */
3174
3175 if (pPrt->PhyType != SK_PHY_XMAC) {
3176 /* disable GP0 interrupt bit */
3177 IntMask |= XM_IS_INP_ASS;
3178 }
3179 XM_OUT16(IoC, Port, XM_IMSK, IntMask);
3180
3181 /* get MMU Command Reg. */
3182 XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
3183
3184 if (pPrt->PhyType != SK_PHY_XMAC &&
3185 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3186 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
3187 /* set to Full Duplex */
3188 Reg |= XM_MMU_GMII_FD;
3189 }
3190
3191 switch (pPrt->PhyType) {
3192 case SK_PHY_BCOM:
3193 /*
3194 * Workaround BCOM Errata (#10523) for all BCom Phys
3195 * Enable Power Management after link up
3196 */
3197 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
3198 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3199 (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
3200 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
3201 (SK_U16)PHY_B_DEF_MSK);
3202 break;
3203#ifdef OTHER_PHY
3204 case SK_PHY_LONE:
3205 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
3206 break;
3207 case SK_PHY_NAT:
3208 /* todo National:
3209 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
3210 /* no interrupts possible from National ??? */
3211 break;
3212#endif /* OTHER_PHY */
3213 }
3214
3215 /* enable Rx/Tx */
3216 XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
3217 }
3218#endif /* GENESIS */
3219
3220#ifdef YUKON
3221 if (pAC->GIni.GIYukon) {
3222 /*
3223 * Initialize the Interrupt Mask Register. Default IRQs are...
3224 * - Rx Counter Event Overflow
3225 * - Tx Counter Event Overflow
3226 * - Transmit FIFO Underrun
3227 */
3228 IntMask = GMAC_DEF_MSK;
3229
3230#ifdef DEBUG
3231 /* add IRQ for Receive FIFO Overrun */
3232 IntMask |= GM_IS_RX_FF_OR;
3233#endif /* DEBUG */
3234
3235 SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
3236
3237 /* get General Purpose Control */
3238 GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
3239
3240 if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3241 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
3242 /* set to Full Duplex */
3243 Reg |= GM_GPCR_DUP_FULL;
3244 }
3245
3246 /* enable Rx/Tx */
3247 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
3248 GM_GPCR_TX_ENA));
3249
3250#ifndef VCPU
3251 /* Enable all PHY interrupts */
3252 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
3253 (SK_U16)PHY_M_DEF_MSK);
3254#endif /* VCPU */
3255 }
3256#endif /* YUKON */
3257
3258 return(0);
3259
3260} /* SkMacRxTxEnable */
3261
3262
3263/******************************************************************************
3264 *
3265 * SkMacRxTxDisable() - Disable Receiver and Transmitter
3266 *
3267 * Description: disables Rx/Tx dep. on board type
3268 *
3269 * Returns: N/A
3270 */
3271void SkMacRxTxDisable(
3272SK_AC *pAC, /* Adapter Context */
3273SK_IOC IoC, /* IO context */
3274int Port) /* Port Index (MAC_1 + n) */
3275{
3276 SK_U16 Word;
3277
3278#ifdef GENESIS
3279 if (pAC->GIni.GIGenesis) {
3280
3281 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3282
3283 XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
3284
3285 /* dummy read to ensure writing */
3286 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3287 }
3288#endif /* GENESIS */
3289
3290#ifdef YUKON
3291 if (pAC->GIni.GIYukon) {
3292
3293 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3294
3295 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
3296 GM_GPCR_TX_ENA)));
3297
3298 /* dummy read to ensure writing */
3299 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3300 }
3301#endif /* YUKON */
3302
3303} /* SkMacRxTxDisable */
3304
3305
3306/******************************************************************************
3307 *
3308 * SkMacIrqDisable() - Disable IRQ from MAC
3309 *
3310 * Description: sets the IRQ-mask to disable IRQ dep. on board type
3311 *
3312 * Returns: N/A
3313 */
3314void SkMacIrqDisable(
3315SK_AC *pAC, /* Adapter Context */
3316SK_IOC IoC, /* IO context */
3317int Port) /* Port Index (MAC_1 + n) */
3318{
3319 SK_GEPORT *pPrt;
3320#ifdef GENESIS
3321 SK_U16 Word;
3322#endif
3323
3324 pPrt = &pAC->GIni.GP[Port];
3325
3326#ifdef GENESIS
3327 if (pAC->GIni.GIGenesis) {
3328
3329 /* disable all XMAC IRQs */
3330 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
3331
3332 /* Disable all PHY interrupts */
3333 switch (pPrt->PhyType) {
3334 case SK_PHY_BCOM:
3335 /* Make sure that PHY is initialized */
3336 if (pPrt->PState != SK_PRT_RESET) {
3337 /* NOT allowed if BCOM is in RESET state */
3338 /* Workaround BCOM Errata (#10523) all BCom */
3339 /* Disable Power Management if link is down */
3340 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
3341 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3342 (SK_U16)(Word | PHY_B_AC_DIS_PM));
3343 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
3344 }
3345 break;
3346#ifdef OTHER_PHY
3347 case SK_PHY_LONE:
3348 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
3349 break;
3350 case SK_PHY_NAT:
3351 /* todo: National
3352 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
3353 break;
3354#endif /* OTHER_PHY */
3355 }
3356 }
3357#endif /* GENESIS */
3358
3359#ifdef YUKON
3360 if (pAC->GIni.GIYukon) {
3361 /* disable all GMAC IRQs */
3362 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
3363
3364#ifndef VCPU
3365 /* Disable all PHY interrupts */
3366 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
3367#endif /* VCPU */
3368 }
3369#endif /* YUKON */
3370
3371} /* SkMacIrqDisable */
3372
3373
3374#ifdef SK_DIAG
3375/******************************************************************************
3376 *
3377 * SkXmSendCont() - Enable / Disable Send Continuous Mode
3378 *
3379 * Description: enable / disable Send Continuous Mode on XMAC
3380 *
3381 * Returns:
3382 * nothing
3383 */
3384void SkXmSendCont(
3385SK_AC *pAC, /* adapter context */
3386SK_IOC IoC, /* IO context */
3387int Port, /* Port Index (MAC_1 + n) */
3388SK_BOOL Enable) /* Enable / Disable */
3389{
3390 SK_U32 MdReg;
3391
3392 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3393
3394 if (Enable) {
3395 MdReg |= XM_MD_TX_CONT;
3396 }
3397 else {
3398 MdReg &= ~XM_MD_TX_CONT;
3399 }
3400 /* setup Mode Register */
3401 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3402
3403} /* SkXmSendCont */
3404
3405
3406/******************************************************************************
3407 *
3408 * SkMacTimeStamp() - Enable / Disable Time Stamp
3409 *
3410 * Description: enable / disable Time Stamp generation for Rx packets
3411 *
3412 * Returns:
3413 * nothing
3414 */
3415void SkMacTimeStamp(
3416SK_AC *pAC, /* adapter context */
3417SK_IOC IoC, /* IO context */
3418int Port, /* Port Index (MAC_1 + n) */
3419SK_BOOL Enable) /* Enable / Disable */
3420{
3421 SK_U32 MdReg;
3422 SK_U8 TimeCtrl;
3423
3424 if (pAC->GIni.GIGenesis) {
3425
3426 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3427
3428 if (Enable) {
3429 MdReg |= XM_MD_ATS;
3430 }
3431 else {
3432 MdReg &= ~XM_MD_ATS;
3433 }
3434 /* setup Mode Register */
3435 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3436 }
3437 else {
3438 if (Enable) {
3439 TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
3440 }
3441 else {
3442 TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
3443 }
3444 /* Start/Stop Time Stamp Timer */
3445 SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl);
3446 }
3447
3448} /* SkMacTimeStamp*/
3449
3450#else /* !SK_DIAG */
3451
3452#ifdef GENESIS
3453/******************************************************************************
3454 *
3455 * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
3456 *
3457 * This function analyses the Interrupt status word. If any of the
3458 * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
3459 * is set true.
3460 */
3461void SkXmAutoNegLipaXmac(
3462SK_AC *pAC, /* adapter context */
3463SK_IOC IoC, /* IO context */
3464int Port, /* Port Index (MAC_1 + n) */
3465SK_U16 IStatus) /* Interrupt Status word to analyse */
3466{
3467 SK_GEPORT *pPrt;
3468
3469 pPrt = &pAC->GIni.GP[Port];
3470
3471 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3472 (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
3473
3474 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3475 ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n",
3476 Port, IStatus));
3477 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3478 }
3479} /* SkXmAutoNegLipaXmac */
3480#endif /* GENESIS */
3481
3482
3483/******************************************************************************
3484 *
3485 * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
3486 *
3487 * This function analyses the PHY status word.
3488 * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
3489 * is set true.
3490 */
3491void SkMacAutoNegLipaPhy(
3492SK_AC *pAC, /* adapter context */
3493SK_IOC IoC, /* IO context */
3494int Port, /* Port Index (MAC_1 + n) */
3495SK_U16 PhyStat) /* PHY Status word to analyse */
3496{
3497 SK_GEPORT *pPrt;
3498
3499 pPrt = &pAC->GIni.GP[Port];
3500
3501 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3502 (PhyStat & PHY_ST_AN_OVER) != 0) {
3503
3504 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3505 ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n",
3506 Port, PhyStat));
3507 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3508 }
3509} /* SkMacAutoNegLipaPhy */
3510
3511
3512#ifdef GENESIS
3513/******************************************************************************
3514 *
3515 * SkXmIrq() - Interrupt Service Routine
3516 *
3517 * Description: services an Interrupt Request of the XMAC
3518 *
3519 * Note:
3520 * With an external PHY, some interrupt bits are not meaningfull any more:
3521 * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE
3522 * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC
3523 * - Page Received (bit #9) XM_IS_RX_PAGE
3524 * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE
3525 * - AutoNegDone (bit #7) XM_IS_AND
3526 * Also probably not valid any more is the GP0 input bit:
3527 * - GPRegisterBit0set XM_IS_INP_ASS
3528 *
3529 * Returns:
3530 * nothing
3531 */
3532static void SkXmIrq(
3533SK_AC *pAC, /* adapter context */
3534SK_IOC IoC, /* IO context */
3535int Port) /* Port Index (MAC_1 + n) */
3536{
3537 SK_GEPORT *pPrt;
3538 SK_EVPARA Para;
3539 SK_U16 IStatus; /* Interrupt status read from the XMAC */
3540 SK_U16 IStatus2;
3541#ifdef SK_SLIM
3542 SK_U64 OverflowStatus;
3543#endif
3544
3545 pPrt = &pAC->GIni.GP[Port];
3546
3547 XM_IN16(IoC, Port, XM_ISRC, &IStatus);
3548
3549 /* LinkPartner Auto-negable? */
3550 if (pPrt->PhyType == SK_PHY_XMAC) {
3551 SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
3552 }
3553 else {
3554 /* mask bits that are not used with ext. PHY */
3555 IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
3556 XM_IS_RX_PAGE | XM_IS_TX_PAGE |
3557 XM_IS_AND | XM_IS_INP_ASS);
3558 }
3559
3560 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3561 ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
3562
3563 if (!pPrt->PHWLinkUp) {
3564 /* Spurious XMAC interrupt */
3565 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3566 ("SkXmIrq: spurious interrupt on Port %d\n", Port));
3567 return;
3568 }
3569
3570 if ((IStatus & XM_IS_INP_ASS) != 0) {
3571 /* Reread ISR Register if link is not in sync */
3572 XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
3573
3574 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3575 ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n",
3576 Port, IStatus, IStatus2));
3577 IStatus &= ~XM_IS_INP_ASS;
3578 IStatus |= IStatus2;
3579 }
3580
3581 if ((IStatus & XM_IS_LNK_AE) != 0) {
3582 /* not used, GP0 is used instead */
3583 }
3584
3585 if ((IStatus & XM_IS_TX_ABORT) != 0) {
3586 /* not used */
3587 }
3588
3589 if ((IStatus & XM_IS_FRC_INT) != 0) {
3590 /* not used, use ASIC IRQ instead if needed */
3591 }
3592
3593 if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
3594 SkHWLinkDown(pAC, IoC, Port);
3595
3596 /* Signal to RLMT */
3597 Para.Para32[0] = (SK_U32)Port;
3598 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
3599
3600 /* Start workaround Errata #2 timer */
3601 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
3602 SKGE_HWAC, SK_HWEV_WATIM, Para);
3603 }
3604
3605 if ((IStatus & XM_IS_RX_PAGE) != 0) {
3606 /* not used */
3607 }
3608
3609 if ((IStatus & XM_IS_TX_PAGE) != 0) {
3610 /* not used */
3611 }
3612
3613 if ((IStatus & XM_IS_AND) != 0) {
3614 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3615 ("SkXmIrq: AND on link that is up Port %d\n", Port));
3616 }
3617
3618 if ((IStatus & XM_IS_TSC_OV) != 0) {
3619 /* not used */
3620 }
3621
3622 /* Combined Tx & Rx Counter Overflow SIRQ Event */
3623 if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
3624#ifdef SK_SLIM
3625 SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
3626#else
3627 Para.Para32[0] = (SK_U32)Port;
3628 Para.Para32[1] = (SK_U32)IStatus;
3629 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
3630#endif /* SK_SLIM */
3631 }
3632
3633 if ((IStatus & XM_IS_RXF_OV) != 0) {
3634 /* normal situation -> no effect */
3635#ifdef DEBUG
3636 pPrt->PRxOverCnt++;
3637#endif /* DEBUG */
3638 }
3639
3640 if ((IStatus & XM_IS_TXF_UR) != 0) {
3641 /* may NOT happen -> error log */
3642 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
3643 }
3644
3645 if ((IStatus & XM_IS_TX_COMP) != 0) {
3646 /* not served here */
3647 }
3648
3649 if ((IStatus & XM_IS_RX_COMP) != 0) {
3650 /* not served here */
3651 }
3652} /* SkXmIrq */
3653#endif /* GENESIS */
3654
3655
3656#ifdef YUKON
3657/******************************************************************************
3658 *
3659 * SkGmIrq() - Interrupt Service Routine
3660 *
3661 * Description: services an Interrupt Request of the GMAC
3662 *
3663 * Note:
3664 *
3665 * Returns:
3666 * nothing
3667 */
3668static void SkGmIrq(
3669SK_AC *pAC, /* adapter context */
3670SK_IOC IoC, /* IO context */
3671int Port) /* Port Index (MAC_1 + n) */
3672{
3673 SK_GEPORT *pPrt;
3674 SK_U8 IStatus; /* Interrupt status */
3675#ifdef SK_SLIM
3676 SK_U64 OverflowStatus;
3677#else
3678 SK_EVPARA Para;
3679#endif
3680
3681 pPrt = &pAC->GIni.GP[Port];
3682
3683 SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
3684
3685#ifdef XXX
3686 /* LinkPartner Auto-negable? */
3687 SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
3688#endif /* XXX */
3689
3690 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3691 ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
3692
3693 /* Combined Tx & Rx Counter Overflow SIRQ Event */
3694 if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
3695 /* these IRQs will be cleared by reading GMACs register */
3696#ifdef SK_SLIM
3697 SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
3698#else
3699 Para.Para32[0] = (SK_U32)Port;
3700 Para.Para32[1] = (SK_U32)IStatus;
3701 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
3702#endif
3703 }
3704
3705 if (IStatus & GM_IS_RX_FF_OR) {
3706 /* clear GMAC Rx FIFO Overrun IRQ */
3707 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
3708#ifdef DEBUG
3709 pPrt->PRxOverCnt++;
3710#endif /* DEBUG */
3711 }
3712
3713 if (IStatus & GM_IS_TX_FF_UR) {
3714 /* clear GMAC Tx FIFO Underrun IRQ */
3715 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
3716 /* may NOT happen -> error log */
3717 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
3718 }
3719
3720 if (IStatus & GM_IS_TX_COMPL) {
3721 /* not served here */
3722 }
3723
3724 if (IStatus & GM_IS_RX_COMPL) {
3725 /* not served here */
3726 }
3727} /* SkGmIrq */
3728#endif /* YUKON */
3729
3730
3731/******************************************************************************
3732 *
3733 * SkMacIrq() - Interrupt Service Routine for MAC
3734 *
3735 * Description: calls the Interrupt Service Routine dep. on board type
3736 *
3737 * Returns:
3738 * nothing
3739 */
3740void SkMacIrq(
3741SK_AC *pAC, /* adapter context */
3742SK_IOC IoC, /* IO context */
3743int Port) /* Port Index (MAC_1 + n) */
3744{
3745#ifdef GENESIS
3746 if (pAC->GIni.GIGenesis) {
3747 /* IRQ from XMAC */
3748 SkXmIrq(pAC, IoC, Port);
3749 }
3750#endif /* GENESIS */
3751
3752#ifdef YUKON
3753 if (pAC->GIni.GIYukon) {
3754 /* IRQ from GMAC */
3755 SkGmIrq(pAC, IoC, Port);
3756 }
3757#endif /* YUKON */
3758
3759} /* SkMacIrq */
3760
3761#endif /* !SK_DIAG */
3762
3763#ifdef GENESIS
3764/******************************************************************************
3765 *
3766 * SkXmUpdateStats() - Force the XMAC to output the current statistic
3767 *
3768 * Description:
3769 * The XMAC holds its statistic internally. To obtain the current
3770 * values a command must be sent so that the statistic data will
3771 * be written to a predefined memory area on the adapter.
3772 *
3773 * Returns:
3774 * 0: success
3775 * 1: something went wrong
3776 */
3777int SkXmUpdateStats(
3778SK_AC *pAC, /* adapter context */
3779SK_IOC IoC, /* IO context */
3780unsigned int Port) /* Port Index (MAC_1 + n) */
3781{
3782 SK_GEPORT *pPrt;
3783 SK_U16 StatReg;
3784 int WaitIndex;
3785
3786 pPrt = &pAC->GIni.GP[Port];
3787 WaitIndex = 0;
3788
3789 /* Send an update command to XMAC specified */
3790 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
3791
3792 /*
3793 * It is an auto-clearing register. If the command bits
3794 * went to zero again, the statistics are transferred.
3795 * Normally the command should be executed immediately.
3796 * But just to be sure we execute a loop.
3797 */
3798 do {
3799
3800 XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
3801
3802 if (++WaitIndex > 10) {
3803
3804 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
3805
3806 return(1);
3807 }
3808 } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
3809
3810 return(0);
3811} /* SkXmUpdateStats */
3812
3813
3814/******************************************************************************
3815 *
3816 * SkXmMacStatistic() - Get XMAC counter value
3817 *
3818 * Description:
3819 * Gets the 32bit counter value. Except for the octet counters
3820 * the lower 32bit are counted in hardware and the upper 32bit
3821 * must be counted in software by monitoring counter overflow interrupts.
3822 *
3823 * Returns:
3824 * 0: success
3825 * 1: something went wrong
3826 */
3827int SkXmMacStatistic(
3828SK_AC *pAC, /* adapter context */
3829SK_IOC IoC, /* IO context */
3830unsigned int Port, /* Port Index (MAC_1 + n) */
3831SK_U16 StatAddr, /* MIB counter base address */
3832SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
3833{
3834 if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
3835
3836 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
3837
3838 return(1);
3839 }
3840
3841 XM_IN32(IoC, Port, StatAddr, pVal);
3842
3843 return(0);
3844} /* SkXmMacStatistic */
3845
3846
3847/******************************************************************************
3848 *
3849 * SkXmResetCounter() - Clear MAC statistic counter
3850 *
3851 * Description:
3852 * Force the XMAC to clear its statistic counter.
3853 *
3854 * Returns:
3855 * 0: success
3856 * 1: something went wrong
3857 */
3858int SkXmResetCounter(
3859SK_AC *pAC, /* adapter context */
3860SK_IOC IoC, /* IO context */
3861unsigned int Port) /* Port Index (MAC_1 + n) */
3862{
3863 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
3864 /* Clear two times according to Errata #3 */
3865 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
3866
3867 return(0);
3868} /* SkXmResetCounter */
3869
3870
3871/******************************************************************************
3872 *
3873 * SkXmOverflowStatus() - Gets the status of counter overflow interrupt
3874 *
3875 * Description:
3876 * Checks the source causing an counter overflow interrupt. On success the
3877 * resulting counter overflow status is written to <pStatus>, whereas the
3878 * upper dword stores the XMAC ReceiveCounterEvent register and the lower
3879 * dword the XMAC TransmitCounterEvent register.
3880 *
3881 * Note:
3882 * For XMAC the interrupt source is a self-clearing register, so the source
3883 * must be checked only once. SIRQ module does another check to be sure
3884 * that no interrupt get lost during process time.
3885 *
3886 * Returns:
3887 * 0: success
3888 * 1: something went wrong
3889 */
3890int SkXmOverflowStatus(
3891SK_AC *pAC, /* adapter context */
3892SK_IOC IoC, /* IO context */
3893unsigned int Port, /* Port Index (MAC_1 + n) */
3894SK_U16 IStatus, /* Interupt Status from MAC */
3895SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
3896{
3897 SK_U64 Status; /* Overflow status */
3898 SK_U32 RegVal;
3899
3900 Status = 0;
3901
3902 if ((IStatus & XM_IS_RXC_OV) != 0) {
3903
3904 XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
3905 Status |= (SK_U64)RegVal << 32;
3906 }
3907
3908 if ((IStatus & XM_IS_TXC_OV) != 0) {
3909
3910 XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
3911 Status |= (SK_U64)RegVal;
3912 }
3913
3914 *pStatus = Status;
3915
3916 return(0);
3917} /* SkXmOverflowStatus */
3918#endif /* GENESIS */
3919
3920
3921#ifdef YUKON
3922/******************************************************************************
3923 *
3924 * SkGmUpdateStats() - Force the GMAC to output the current statistic
3925 *
3926 * Description:
3927 * Empty function for GMAC. Statistic data is accessible in direct way.
3928 *
3929 * Returns:
3930 * 0: success
3931 * 1: something went wrong
3932 */
3933int SkGmUpdateStats(
3934SK_AC *pAC, /* adapter context */
3935SK_IOC IoC, /* IO context */
3936unsigned int Port) /* Port Index (MAC_1 + n) */
3937{
3938 return(0);
3939}
3940
3941
3942/******************************************************************************
3943 *
3944 * SkGmMacStatistic() - Get GMAC counter value
3945 *
3946 * Description:
3947 * Gets the 32bit counter value. Except for the octet counters
3948 * the lower 32bit are counted in hardware and the upper 32bit
3949 * must be counted in software by monitoring counter overflow interrupts.
3950 *
3951 * Returns:
3952 * 0: success
3953 * 1: something went wrong
3954 */
3955int SkGmMacStatistic(
3956SK_AC *pAC, /* adapter context */
3957SK_IOC IoC, /* IO context */
3958unsigned int Port, /* Port Index (MAC_1 + n) */
3959SK_U16 StatAddr, /* MIB counter base address */
3960SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
3961{
3962
3963 if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
3964
3965 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
3966
3967 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3968 ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
3969 return(1);
3970 }
3971
3972 GM_IN32(IoC, Port, StatAddr, pVal);
3973
3974 return(0);
3975} /* SkGmMacStatistic */
3976
3977
3978/******************************************************************************
3979 *
3980 * SkGmResetCounter() - Clear MAC statistic counter
3981 *
3982 * Description:
3983 * Force GMAC to clear its statistic counter.
3984 *
3985 * Returns:
3986 * 0: success
3987 * 1: something went wrong
3988 */
3989int SkGmResetCounter(
3990SK_AC *pAC, /* adapter context */
3991SK_IOC IoC, /* IO context */
3992unsigned int Port) /* Port Index (MAC_1 + n) */
3993{
3994 SK_U16 Reg; /* Phy Address Register */
3995 SK_U16 Word;
3996 int i;
3997
3998 GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
3999
4000 /* set MIB Clear Counter Mode */
4001 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
4002
4003 /* read all MIB Counters with Clear Mode set */
4004 for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
4005 /* the reset is performed only when the lower 16 bits are read */
4006 GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
4007 }
4008
4009 /* clear MIB Clear Counter Mode */
4010 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
4011
4012 return(0);
4013} /* SkGmResetCounter */
4014
4015
4016/******************************************************************************
4017 *
4018 * SkGmOverflowStatus() - Gets the status of counter overflow interrupt
4019 *
4020 * Description:
4021 * Checks the source causing an counter overflow interrupt. On success the
4022 * resulting counter overflow status is written to <pStatus>, whereas the
4023 * the following bit coding is used:
4024 * 63:56 - unused
4025 * 55:48 - TxRx interrupt register bit7:0
4026 * 32:47 - Rx interrupt register
4027 * 31:24 - unused
4028 * 23:16 - TxRx interrupt register bit15:8
4029 * 15:0 - Tx interrupt register
4030 *
4031 * Returns:
4032 * 0: success
4033 * 1: something went wrong
4034 */
4035int SkGmOverflowStatus(
4036SK_AC *pAC, /* adapter context */
4037SK_IOC IoC, /* IO context */
4038unsigned int Port, /* Port Index (MAC_1 + n) */
4039SK_U16 IStatus, /* Interupt Status from MAC */
4040SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
4041{
4042 SK_U64 Status; /* Overflow status */
4043 SK_U16 RegVal;
4044
4045 Status = 0;
4046
4047 if ((IStatus & GM_IS_RX_CO_OV) != 0) {
4048 /* this register is self-clearing after read */
4049 GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
4050 Status |= (SK_U64)RegVal << 32;
4051 }
4052
4053 if ((IStatus & GM_IS_TX_CO_OV) != 0) {
4054 /* this register is self-clearing after read */
4055 GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
4056 Status |= (SK_U64)RegVal;
4057 }
4058
4059 /* this register is self-clearing after read */
4060 GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
4061 /* Rx overflow interrupt register bits (LoByte)*/
4062 Status |= (SK_U64)((SK_U8)RegVal) << 48;
4063 /* Tx overflow interrupt register bits (HiByte)*/
4064 Status |= (SK_U64)(RegVal >> 8) << 16;
4065
4066 *pStatus = Status;
4067
4068 return(0);
4069} /* SkGmOverflowStatus */
4070
4071
4072#ifndef SK_SLIM
4073/******************************************************************************
4074 *
4075 * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
4076 *
4077 * Description:
4078 * starts the cable diagnostic test if 'StartTest' is true
4079 * gets the results if 'StartTest' is true
4080 *
4081 * NOTE: this test is meaningful only when link is down
4082 *
4083 * Returns:
4084 * 0: success
4085 * 1: no YUKON copper
4086 * 2: test in progress
4087 */
4088int SkGmCableDiagStatus(
4089SK_AC *pAC, /* adapter context */
4090SK_IOC IoC, /* IO context */
4091int Port, /* Port Index (MAC_1 + n) */
4092SK_BOOL StartTest) /* flag for start / get result */
4093{
4094 int i;
4095 SK_U16 RegVal;
4096 SK_GEPORT *pPrt;
4097
4098 pPrt = &pAC->GIni.GP[Port];
4099
4100 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
4101
4102 return(1);
4103 }
4104
4105 if (StartTest) {
4106 /* only start the cable test */
4107 if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
4108 /* apply TDR workaround from Marvell */
4109 SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
4110
4111 SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
4112 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
4113 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
4114 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
4115 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
4116 }
4117
4118 /* set address to 0 for MDI[0] */
4119 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
4120
4121 /* Read Cable Diagnostic Reg */
4122 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4123
4124 /* start Cable Diagnostic Test */
4125 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
4126 (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
4127
4128 return(0);
4129 }
4130
4131 /* Read Cable Diagnostic Reg */
4132 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4133
4134 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
4135 ("PHY Cable Diag.=0x%04X\n", RegVal));
4136
4137 if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
4138 /* test is running */
4139 return(2);
4140 }
4141
4142 /* get the test results */
4143 for (i = 0; i < 4; i++) {
4144 /* set address to i for MDI[i] */
4145 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
4146
4147 /* get Cable Diagnostic values */
4148 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4149
4150 pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
4151
4152 pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
4153 }
4154
4155 return(0);
4156} /* SkGmCableDiagStatus */
4157#endif /* !SK_SLIM */
4158#endif /* YUKON */
4159
4160/* End of file */
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 4020e9e955b3..97bdb2a43bc8 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -220,22 +220,22 @@ static void PRINT_PKT(u_char *buf, int length)
220 220
221 221
222/* this enables an interrupt in the interrupt mask register */ 222/* this enables an interrupt in the interrupt mask register */
223#define SMC_ENABLE_INT(x) do { \ 223#define SMC_ENABLE_INT(lp, x) do { \
224 unsigned char mask; \ 224 unsigned char mask; \
225 spin_lock_irq(&lp->lock); \ 225 spin_lock_irq(&lp->lock); \
226 mask = SMC_GET_INT_MASK(); \ 226 mask = SMC_GET_INT_MASK(lp); \
227 mask |= (x); \ 227 mask |= (x); \
228 SMC_SET_INT_MASK(mask); \ 228 SMC_SET_INT_MASK(lp, mask); \
229 spin_unlock_irq(&lp->lock); \ 229 spin_unlock_irq(&lp->lock); \
230} while (0) 230} while (0)
231 231
232/* this disables an interrupt from the interrupt mask register */ 232/* this disables an interrupt from the interrupt mask register */
233#define SMC_DISABLE_INT(x) do { \ 233#define SMC_DISABLE_INT(lp, x) do { \
234 unsigned char mask; \ 234 unsigned char mask; \
235 spin_lock_irq(&lp->lock); \ 235 spin_lock_irq(&lp->lock); \
236 mask = SMC_GET_INT_MASK(); \ 236 mask = SMC_GET_INT_MASK(lp); \
237 mask &= ~(x); \ 237 mask &= ~(x); \
238 SMC_SET_INT_MASK(mask); \ 238 SMC_SET_INT_MASK(lp, mask); \
239 spin_unlock_irq(&lp->lock); \ 239 spin_unlock_irq(&lp->lock); \
240} while (0) 240} while (0)
241 241
@@ -244,10 +244,10 @@ static void PRINT_PKT(u_char *buf, int length)
244 * if at all, but let's avoid deadlocking the system if the hardware 244 * if at all, but let's avoid deadlocking the system if the hardware
245 * decides to go south. 245 * decides to go south.
246 */ 246 */
247#define SMC_WAIT_MMU_BUSY() do { \ 247#define SMC_WAIT_MMU_BUSY(lp) do { \
248 if (unlikely(SMC_GET_MMU_CMD() & MC_BUSY)) { \ 248 if (unlikely(SMC_GET_MMU_CMD(lp) & MC_BUSY)) { \
249 unsigned long timeout = jiffies + 2; \ 249 unsigned long timeout = jiffies + 2; \
250 while (SMC_GET_MMU_CMD() & MC_BUSY) { \ 250 while (SMC_GET_MMU_CMD(lp) & MC_BUSY) { \
251 if (time_after(jiffies, timeout)) { \ 251 if (time_after(jiffies, timeout)) { \
252 printk("%s: timeout %s line %d\n", \ 252 printk("%s: timeout %s line %d\n", \
253 dev->name, __FILE__, __LINE__); \ 253 dev->name, __FILE__, __LINE__); \
@@ -273,8 +273,8 @@ static void smc_reset(struct net_device *dev)
273 273
274 /* Disable all interrupts, block TX tasklet */ 274 /* Disable all interrupts, block TX tasklet */
275 spin_lock_irq(&lp->lock); 275 spin_lock_irq(&lp->lock);
276 SMC_SELECT_BANK(2); 276 SMC_SELECT_BANK(lp, 2);
277 SMC_SET_INT_MASK(0); 277 SMC_SET_INT_MASK(lp, 0);
278 pending_skb = lp->pending_tx_skb; 278 pending_skb = lp->pending_tx_skb;
279 lp->pending_tx_skb = NULL; 279 lp->pending_tx_skb = NULL;
280 spin_unlock_irq(&lp->lock); 280 spin_unlock_irq(&lp->lock);
@@ -290,15 +290,15 @@ static void smc_reset(struct net_device *dev)
290 * This resets the registers mostly to defaults, but doesn't 290 * This resets the registers mostly to defaults, but doesn't
291 * affect EEPROM. That seems unnecessary 291 * affect EEPROM. That seems unnecessary
292 */ 292 */
293 SMC_SELECT_BANK(0); 293 SMC_SELECT_BANK(lp, 0);
294 SMC_SET_RCR(RCR_SOFTRST); 294 SMC_SET_RCR(lp, RCR_SOFTRST);
295 295
296 /* 296 /*
297 * Setup the Configuration Register 297 * Setup the Configuration Register
298 * This is necessary because the CONFIG_REG is not affected 298 * This is necessary because the CONFIG_REG is not affected
299 * by a soft reset 299 * by a soft reset
300 */ 300 */
301 SMC_SELECT_BANK(1); 301 SMC_SELECT_BANK(lp, 1);
302 302
303 cfg = CONFIG_DEFAULT; 303 cfg = CONFIG_DEFAULT;
304 304
@@ -316,7 +316,7 @@ static void smc_reset(struct net_device *dev)
316 */ 316 */
317 cfg |= CONFIG_EPH_POWER_EN; 317 cfg |= CONFIG_EPH_POWER_EN;
318 318
319 SMC_SET_CONFIG(cfg); 319 SMC_SET_CONFIG(lp, cfg);
320 320
321 /* this should pause enough for the chip to be happy */ 321 /* this should pause enough for the chip to be happy */
322 /* 322 /*
@@ -329,12 +329,12 @@ static void smc_reset(struct net_device *dev)
329 udelay(1); 329 udelay(1);
330 330
331 /* Disable transmit and receive functionality */ 331 /* Disable transmit and receive functionality */
332 SMC_SELECT_BANK(0); 332 SMC_SELECT_BANK(lp, 0);
333 SMC_SET_RCR(RCR_CLEAR); 333 SMC_SET_RCR(lp, RCR_CLEAR);
334 SMC_SET_TCR(TCR_CLEAR); 334 SMC_SET_TCR(lp, TCR_CLEAR);
335 335
336 SMC_SELECT_BANK(1); 336 SMC_SELECT_BANK(lp, 1);
337 ctl = SMC_GET_CTL() | CTL_LE_ENABLE; 337 ctl = SMC_GET_CTL(lp) | CTL_LE_ENABLE;
338 338
339 /* 339 /*
340 * Set the control register to automatically release successfully 340 * Set the control register to automatically release successfully
@@ -345,12 +345,12 @@ static void smc_reset(struct net_device *dev)
345 ctl |= CTL_AUTO_RELEASE; 345 ctl |= CTL_AUTO_RELEASE;
346 else 346 else
347 ctl &= ~CTL_AUTO_RELEASE; 347 ctl &= ~CTL_AUTO_RELEASE;
348 SMC_SET_CTL(ctl); 348 SMC_SET_CTL(lp, ctl);
349 349
350 /* Reset the MMU */ 350 /* Reset the MMU */
351 SMC_SELECT_BANK(2); 351 SMC_SELECT_BANK(lp, 2);
352 SMC_SET_MMU_CMD(MC_RESET); 352 SMC_SET_MMU_CMD(lp, MC_RESET);
353 SMC_WAIT_MMU_BUSY(); 353 SMC_WAIT_MMU_BUSY(lp);
354} 354}
355 355
356/* 356/*
@@ -365,19 +365,19 @@ static void smc_enable(struct net_device *dev)
365 DBG(2, "%s: %s\n", dev->name, __FUNCTION__); 365 DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
366 366
367 /* see the header file for options in TCR/RCR DEFAULT */ 367 /* see the header file for options in TCR/RCR DEFAULT */
368 SMC_SELECT_BANK(0); 368 SMC_SELECT_BANK(lp, 0);
369 SMC_SET_TCR(lp->tcr_cur_mode); 369 SMC_SET_TCR(lp, lp->tcr_cur_mode);
370 SMC_SET_RCR(lp->rcr_cur_mode); 370 SMC_SET_RCR(lp, lp->rcr_cur_mode);
371 371
372 SMC_SELECT_BANK(1); 372 SMC_SELECT_BANK(lp, 1);
373 SMC_SET_MAC_ADDR(dev->dev_addr); 373 SMC_SET_MAC_ADDR(lp, dev->dev_addr);
374 374
375 /* now, enable interrupts */ 375 /* now, enable interrupts */
376 mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT; 376 mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT;
377 if (lp->version >= (CHIP_91100 << 4)) 377 if (lp->version >= (CHIP_91100 << 4))
378 mask |= IM_MDINT; 378 mask |= IM_MDINT;
379 SMC_SELECT_BANK(2); 379 SMC_SELECT_BANK(lp, 2);
380 SMC_SET_INT_MASK(mask); 380 SMC_SET_INT_MASK(lp, mask);
381 381
382 /* 382 /*
383 * From this point the register bank must _NOT_ be switched away 383 * From this point the register bank must _NOT_ be switched away
@@ -400,8 +400,8 @@ static void smc_shutdown(struct net_device *dev)
400 400
401 /* no more interrupts for me */ 401 /* no more interrupts for me */
402 spin_lock_irq(&lp->lock); 402 spin_lock_irq(&lp->lock);
403 SMC_SELECT_BANK(2); 403 SMC_SELECT_BANK(lp, 2);
404 SMC_SET_INT_MASK(0); 404 SMC_SET_INT_MASK(lp, 0);
405 pending_skb = lp->pending_tx_skb; 405 pending_skb = lp->pending_tx_skb;
406 lp->pending_tx_skb = NULL; 406 lp->pending_tx_skb = NULL;
407 spin_unlock_irq(&lp->lock); 407 spin_unlock_irq(&lp->lock);
@@ -409,14 +409,14 @@ static void smc_shutdown(struct net_device *dev)
409 dev_kfree_skb(pending_skb); 409 dev_kfree_skb(pending_skb);
410 410
411 /* and tell the card to stay away from that nasty outside world */ 411 /* and tell the card to stay away from that nasty outside world */
412 SMC_SELECT_BANK(0); 412 SMC_SELECT_BANK(lp, 0);
413 SMC_SET_RCR(RCR_CLEAR); 413 SMC_SET_RCR(lp, RCR_CLEAR);
414 SMC_SET_TCR(TCR_CLEAR); 414 SMC_SET_TCR(lp, TCR_CLEAR);
415 415
416#ifdef POWER_DOWN 416#ifdef POWER_DOWN
417 /* finally, shut the chip down */ 417 /* finally, shut the chip down */
418 SMC_SELECT_BANK(1); 418 SMC_SELECT_BANK(lp, 1);
419 SMC_SET_CONFIG(SMC_GET_CONFIG() & ~CONFIG_EPH_POWER_EN); 419 SMC_SET_CONFIG(lp, SMC_GET_CONFIG(lp) & ~CONFIG_EPH_POWER_EN);
420#endif 420#endif
421} 421}
422 422
@@ -431,17 +431,17 @@ static inline void smc_rcv(struct net_device *dev)
431 431
432 DBG(3, "%s: %s\n", dev->name, __FUNCTION__); 432 DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
433 433
434 packet_number = SMC_GET_RXFIFO(); 434 packet_number = SMC_GET_RXFIFO(lp);
435 if (unlikely(packet_number & RXFIFO_REMPTY)) { 435 if (unlikely(packet_number & RXFIFO_REMPTY)) {
436 PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name); 436 PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name);
437 return; 437 return;
438 } 438 }
439 439
440 /* read from start of packet */ 440 /* read from start of packet */
441 SMC_SET_PTR(PTR_READ | PTR_RCV | PTR_AUTOINC); 441 SMC_SET_PTR(lp, PTR_READ | PTR_RCV | PTR_AUTOINC);
442 442
443 /* First two words are status and packet length */ 443 /* First two words are status and packet length */
444 SMC_GET_PKT_HDR(status, packet_len); 444 SMC_GET_PKT_HDR(lp, status, packet_len);
445 packet_len &= 0x07ff; /* mask off top bits */ 445 packet_len &= 0x07ff; /* mask off top bits */
446 DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", 446 DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
447 dev->name, packet_number, status, 447 dev->name, packet_number, status,
@@ -460,8 +460,8 @@ static inline void smc_rcv(struct net_device *dev)
460 dev->name, packet_len, status); 460 dev->name, packet_len, status);
461 status |= RS_TOOSHORT; 461 status |= RS_TOOSHORT;
462 } 462 }
463 SMC_WAIT_MMU_BUSY(); 463 SMC_WAIT_MMU_BUSY(lp);
464 SMC_SET_MMU_CMD(MC_RELEASE); 464 SMC_SET_MMU_CMD(lp, MC_RELEASE);
465 dev->stats.rx_errors++; 465 dev->stats.rx_errors++;
466 if (status & RS_ALGNERR) 466 if (status & RS_ALGNERR)
467 dev->stats.rx_frame_errors++; 467 dev->stats.rx_frame_errors++;
@@ -490,8 +490,8 @@ static inline void smc_rcv(struct net_device *dev)
490 if (unlikely(skb == NULL)) { 490 if (unlikely(skb == NULL)) {
491 printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", 491 printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
492 dev->name); 492 dev->name);
493 SMC_WAIT_MMU_BUSY(); 493 SMC_WAIT_MMU_BUSY(lp);
494 SMC_SET_MMU_CMD(MC_RELEASE); 494 SMC_SET_MMU_CMD(lp, MC_RELEASE);
495 dev->stats.rx_dropped++; 495 dev->stats.rx_dropped++;
496 return; 496 return;
497 } 497 }
@@ -510,10 +510,10 @@ static inline void smc_rcv(struct net_device *dev)
510 */ 510 */
511 data_len = packet_len - ((status & RS_ODDFRAME) ? 5 : 6); 511 data_len = packet_len - ((status & RS_ODDFRAME) ? 5 : 6);
512 data = skb_put(skb, data_len); 512 data = skb_put(skb, data_len);
513 SMC_PULL_DATA(data, packet_len - 4); 513 SMC_PULL_DATA(lp, data, packet_len - 4);
514 514
515 SMC_WAIT_MMU_BUSY(); 515 SMC_WAIT_MMU_BUSY(lp);
516 SMC_SET_MMU_CMD(MC_RELEASE); 516 SMC_SET_MMU_CMD(lp, MC_RELEASE);
517 517
518 PRINT_PKT(data, packet_len - 4); 518 PRINT_PKT(data, packet_len - 4);
519 519
@@ -591,7 +591,7 @@ static void smc_hardware_send_pkt(unsigned long data)
591 } 591 }
592 lp->pending_tx_skb = NULL; 592 lp->pending_tx_skb = NULL;
593 593
594 packet_no = SMC_GET_AR(); 594 packet_no = SMC_GET_AR(lp);
595 if (unlikely(packet_no & AR_FAILED)) { 595 if (unlikely(packet_no & AR_FAILED)) {
596 printk("%s: Memory allocation failed.\n", dev->name); 596 printk("%s: Memory allocation failed.\n", dev->name);
597 dev->stats.tx_errors++; 597 dev->stats.tx_errors++;
@@ -601,8 +601,8 @@ static void smc_hardware_send_pkt(unsigned long data)
601 } 601 }
602 602
603 /* point to the beginning of the packet */ 603 /* point to the beginning of the packet */
604 SMC_SET_PN(packet_no); 604 SMC_SET_PN(lp, packet_no);
605 SMC_SET_PTR(PTR_AUTOINC); 605 SMC_SET_PTR(lp, PTR_AUTOINC);
606 606
607 buf = skb->data; 607 buf = skb->data;
608 len = skb->len; 608 len = skb->len;
@@ -614,13 +614,13 @@ static void smc_hardware_send_pkt(unsigned long data)
614 * Send the packet length (+6 for status words, length, and ctl. 614 * Send the packet length (+6 for status words, length, and ctl.
615 * The card will pad to 64 bytes with zeroes if packet is too small. 615 * The card will pad to 64 bytes with zeroes if packet is too small.
616 */ 616 */
617 SMC_PUT_PKT_HDR(0, len + 6); 617 SMC_PUT_PKT_HDR(lp, 0, len + 6);
618 618
619 /* send the actual data */ 619 /* send the actual data */
620 SMC_PUSH_DATA(buf, len & ~1); 620 SMC_PUSH_DATA(lp, buf, len & ~1);
621 621
622 /* Send final ctl word with the last byte if there is one */ 622 /* Send final ctl word with the last byte if there is one */
623 SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG); 623 SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp));
624 624
625 /* 625 /*
626 * If THROTTLE_TX_PKTS is set, we stop the queue here. This will 626 * If THROTTLE_TX_PKTS is set, we stop the queue here. This will
@@ -634,14 +634,14 @@ static void smc_hardware_send_pkt(unsigned long data)
634 netif_stop_queue(dev); 634 netif_stop_queue(dev);
635 635
636 /* queue the packet for TX */ 636 /* queue the packet for TX */
637 SMC_SET_MMU_CMD(MC_ENQUEUE); 637 SMC_SET_MMU_CMD(lp, MC_ENQUEUE);
638 smc_special_unlock(&lp->lock); 638 smc_special_unlock(&lp->lock);
639 639
640 dev->trans_start = jiffies; 640 dev->trans_start = jiffies;
641 dev->stats.tx_packets++; 641 dev->stats.tx_packets++;
642 dev->stats.tx_bytes += len; 642 dev->stats.tx_bytes += len;
643 643
644 SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT); 644 SMC_ENABLE_INT(lp, IM_TX_INT | IM_TX_EMPTY_INT);
645 645
646done: if (!THROTTLE_TX_PKTS) 646done: if (!THROTTLE_TX_PKTS)
647 netif_wake_queue(dev); 647 netif_wake_queue(dev);
@@ -688,7 +688,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
688 smc_special_lock(&lp->lock); 688 smc_special_lock(&lp->lock);
689 689
690 /* now, try to allocate the memory */ 690 /* now, try to allocate the memory */
691 SMC_SET_MMU_CMD(MC_ALLOC | numPages); 691 SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages);
692 692
693 /* 693 /*
694 * Poll the chip for a short amount of time in case the 694 * Poll the chip for a short amount of time in case the
@@ -696,9 +696,9 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
696 */ 696 */
697 poll_count = MEMORY_WAIT_TIME; 697 poll_count = MEMORY_WAIT_TIME;
698 do { 698 do {
699 status = SMC_GET_INT(); 699 status = SMC_GET_INT(lp);
700 if (status & IM_ALLOC_INT) { 700 if (status & IM_ALLOC_INT) {
701 SMC_ACK_INT(IM_ALLOC_INT); 701 SMC_ACK_INT(lp, IM_ALLOC_INT);
702 break; 702 break;
703 } 703 }
704 } while (--poll_count); 704 } while (--poll_count);
@@ -710,7 +710,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
710 /* oh well, wait until the chip finds memory later */ 710 /* oh well, wait until the chip finds memory later */
711 netif_stop_queue(dev); 711 netif_stop_queue(dev);
712 DBG(2, "%s: TX memory allocation deferred.\n", dev->name); 712 DBG(2, "%s: TX memory allocation deferred.\n", dev->name);
713 SMC_ENABLE_INT(IM_ALLOC_INT); 713 SMC_ENABLE_INT(lp, IM_ALLOC_INT);
714 } else { 714 } else {
715 /* 715 /*
716 * Allocation succeeded: push packet to the chip's own memory 716 * Allocation succeeded: push packet to the chip's own memory
@@ -736,19 +736,19 @@ static void smc_tx(struct net_device *dev)
736 DBG(3, "%s: %s\n", dev->name, __FUNCTION__); 736 DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
737 737
738 /* If the TX FIFO is empty then nothing to do */ 738 /* If the TX FIFO is empty then nothing to do */
739 packet_no = SMC_GET_TXFIFO(); 739 packet_no = SMC_GET_TXFIFO(lp);
740 if (unlikely(packet_no & TXFIFO_TEMPTY)) { 740 if (unlikely(packet_no & TXFIFO_TEMPTY)) {
741 PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name); 741 PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name);
742 return; 742 return;
743 } 743 }
744 744
745 /* select packet to read from */ 745 /* select packet to read from */
746 saved_packet = SMC_GET_PN(); 746 saved_packet = SMC_GET_PN(lp);
747 SMC_SET_PN(packet_no); 747 SMC_SET_PN(lp, packet_no);
748 748
749 /* read the first word (status word) from this packet */ 749 /* read the first word (status word) from this packet */
750 SMC_SET_PTR(PTR_AUTOINC | PTR_READ); 750 SMC_SET_PTR(lp, PTR_AUTOINC | PTR_READ);
751 SMC_GET_PKT_HDR(tx_status, pkt_len); 751 SMC_GET_PKT_HDR(lp, tx_status, pkt_len);
752 DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n", 752 DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n",
753 dev->name, tx_status, packet_no); 753 dev->name, tx_status, packet_no);
754 754
@@ -771,17 +771,17 @@ static void smc_tx(struct net_device *dev)
771 } 771 }
772 772
773 /* kill the packet */ 773 /* kill the packet */
774 SMC_WAIT_MMU_BUSY(); 774 SMC_WAIT_MMU_BUSY(lp);
775 SMC_SET_MMU_CMD(MC_FREEPKT); 775 SMC_SET_MMU_CMD(lp, MC_FREEPKT);
776 776
777 /* Don't restore Packet Number Reg until busy bit is cleared */ 777 /* Don't restore Packet Number Reg until busy bit is cleared */
778 SMC_WAIT_MMU_BUSY(); 778 SMC_WAIT_MMU_BUSY(lp);
779 SMC_SET_PN(saved_packet); 779 SMC_SET_PN(lp, saved_packet);
780 780
781 /* re-enable transmit */ 781 /* re-enable transmit */
782 SMC_SELECT_BANK(0); 782 SMC_SELECT_BANK(lp, 0);
783 SMC_SET_TCR(lp->tcr_cur_mode); 783 SMC_SET_TCR(lp, lp->tcr_cur_mode);
784 SMC_SELECT_BANK(2); 784 SMC_SELECT_BANK(lp, 2);
785} 785}
786 786
787 787
@@ -793,7 +793,7 @@ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
793 void __iomem *ioaddr = lp->base; 793 void __iomem *ioaddr = lp->base;
794 unsigned int mii_reg, mask; 794 unsigned int mii_reg, mask;
795 795
796 mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO); 796 mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO);
797 mii_reg |= MII_MDOE; 797 mii_reg |= MII_MDOE;
798 798
799 for (mask = 1 << (bits - 1); mask; mask >>= 1) { 799 for (mask = 1 << (bits - 1); mask; mask >>= 1) {
@@ -802,9 +802,9 @@ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
802 else 802 else
803 mii_reg &= ~MII_MDO; 803 mii_reg &= ~MII_MDO;
804 804
805 SMC_SET_MII(mii_reg); 805 SMC_SET_MII(lp, mii_reg);
806 udelay(MII_DELAY); 806 udelay(MII_DELAY);
807 SMC_SET_MII(mii_reg | MII_MCLK); 807 SMC_SET_MII(lp, mii_reg | MII_MCLK);
808 udelay(MII_DELAY); 808 udelay(MII_DELAY);
809 } 809 }
810} 810}
@@ -815,16 +815,16 @@ static unsigned int smc_mii_in(struct net_device *dev, int bits)
815 void __iomem *ioaddr = lp->base; 815 void __iomem *ioaddr = lp->base;
816 unsigned int mii_reg, mask, val; 816 unsigned int mii_reg, mask, val;
817 817
818 mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO); 818 mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO);
819 SMC_SET_MII(mii_reg); 819 SMC_SET_MII(lp, mii_reg);
820 820
821 for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) { 821 for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) {
822 if (SMC_GET_MII() & MII_MDI) 822 if (SMC_GET_MII(lp) & MII_MDI)
823 val |= mask; 823 val |= mask;
824 824
825 SMC_SET_MII(mii_reg); 825 SMC_SET_MII(lp, mii_reg);
826 udelay(MII_DELAY); 826 udelay(MII_DELAY);
827 SMC_SET_MII(mii_reg | MII_MCLK); 827 SMC_SET_MII(lp, mii_reg | MII_MCLK);
828 udelay(MII_DELAY); 828 udelay(MII_DELAY);
829 } 829 }
830 830
@@ -840,7 +840,7 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
840 void __iomem *ioaddr = lp->base; 840 void __iomem *ioaddr = lp->base;
841 unsigned int phydata; 841 unsigned int phydata;
842 842
843 SMC_SELECT_BANK(3); 843 SMC_SELECT_BANK(lp, 3);
844 844
845 /* Idle - 32 ones */ 845 /* Idle - 32 ones */
846 smc_mii_out(dev, 0xffffffff, 32); 846 smc_mii_out(dev, 0xffffffff, 32);
@@ -852,12 +852,12 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
852 phydata = smc_mii_in(dev, 18); 852 phydata = smc_mii_in(dev, 18);
853 853
854 /* Return to idle state */ 854 /* Return to idle state */
855 SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO)); 855 SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
856 856
857 DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", 857 DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
858 __FUNCTION__, phyaddr, phyreg, phydata); 858 __FUNCTION__, phyaddr, phyreg, phydata);
859 859
860 SMC_SELECT_BANK(2); 860 SMC_SELECT_BANK(lp, 2);
861 return phydata; 861 return phydata;
862} 862}
863 863
@@ -870,7 +870,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
870 struct smc_local *lp = netdev_priv(dev); 870 struct smc_local *lp = netdev_priv(dev);
871 void __iomem *ioaddr = lp->base; 871 void __iomem *ioaddr = lp->base;
872 872
873 SMC_SELECT_BANK(3); 873 SMC_SELECT_BANK(lp, 3);
874 874
875 /* Idle - 32 ones */ 875 /* Idle - 32 ones */
876 smc_mii_out(dev, 0xffffffff, 32); 876 smc_mii_out(dev, 0xffffffff, 32);
@@ -879,12 +879,12 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
879 smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32); 879 smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32);
880 880
881 /* Return to idle state */ 881 /* Return to idle state */
882 SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO)); 882 SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
883 883
884 DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", 884 DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
885 __FUNCTION__, phyaddr, phyreg, phydata); 885 __FUNCTION__, phyaddr, phyreg, phydata);
886 886
887 SMC_SELECT_BANK(2); 887 SMC_SELECT_BANK(lp, 2);
888} 888}
889 889
890/* 890/*
@@ -957,9 +957,9 @@ static int smc_phy_fixed(struct net_device *dev)
957 smc_phy_write(dev, phyaddr, MII_BMCR, bmcr); 957 smc_phy_write(dev, phyaddr, MII_BMCR, bmcr);
958 958
959 /* Re-Configure the Receive/Phy Control register */ 959 /* Re-Configure the Receive/Phy Control register */
960 SMC_SELECT_BANK(0); 960 SMC_SELECT_BANK(lp, 0);
961 SMC_SET_RPC(lp->rpc_cur_mode); 961 SMC_SET_RPC(lp, lp->rpc_cur_mode);
962 SMC_SELECT_BANK(2); 962 SMC_SELECT_BANK(lp, 2);
963 963
964 return 1; 964 return 1;
965} 965}
@@ -1050,8 +1050,8 @@ static void smc_phy_check_media(struct net_device *dev, int init)
1050 lp->tcr_cur_mode &= ~TCR_SWFDUP; 1050 lp->tcr_cur_mode &= ~TCR_SWFDUP;
1051 } 1051 }
1052 1052
1053 SMC_SELECT_BANK(0); 1053 SMC_SELECT_BANK(lp, 0);
1054 SMC_SET_TCR(lp->tcr_cur_mode); 1054 SMC_SET_TCR(lp, lp->tcr_cur_mode);
1055 } 1055 }
1056} 1056}
1057 1057
@@ -1100,8 +1100,8 @@ static void smc_phy_configure(struct work_struct *work)
1100 PHY_INT_SPDDET | PHY_INT_DPLXDET); 1100 PHY_INT_SPDDET | PHY_INT_DPLXDET);
1101 1101
1102 /* Configure the Receive/Phy Control register */ 1102 /* Configure the Receive/Phy Control register */
1103 SMC_SELECT_BANK(0); 1103 SMC_SELECT_BANK(lp, 0);
1104 SMC_SET_RPC(lp->rpc_cur_mode); 1104 SMC_SET_RPC(lp, lp->rpc_cur_mode);
1105 1105
1106 /* If the user requested no auto neg, then go set his request */ 1106 /* If the user requested no auto neg, then go set his request */
1107 if (lp->mii.force_media) { 1107 if (lp->mii.force_media) {
@@ -1158,7 +1158,7 @@ static void smc_phy_configure(struct work_struct *work)
1158 smc_phy_check_media(dev, 1); 1158 smc_phy_check_media(dev, 1);
1159 1159
1160smc_phy_configure_exit: 1160smc_phy_configure_exit:
1161 SMC_SELECT_BANK(2); 1161 SMC_SELECT_BANK(lp, 2);
1162 spin_unlock_irq(&lp->lock); 1162 spin_unlock_irq(&lp->lock);
1163 lp->work_pending = 0; 1163 lp->work_pending = 0;
1164} 1164}
@@ -1200,9 +1200,9 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
1200 1200
1201 old_carrier = netif_carrier_ok(dev) ? 1 : 0; 1201 old_carrier = netif_carrier_ok(dev) ? 1 : 0;
1202 1202
1203 SMC_SELECT_BANK(0); 1203 SMC_SELECT_BANK(lp, 0);
1204 new_carrier = (SMC_GET_EPH_STATUS() & ES_LINK_OK) ? 1 : 0; 1204 new_carrier = (SMC_GET_EPH_STATUS(lp) & ES_LINK_OK) ? 1 : 0;
1205 SMC_SELECT_BANK(2); 1205 SMC_SELECT_BANK(lp, 2);
1206 1206
1207 if (init || (old_carrier != new_carrier)) { 1207 if (init || (old_carrier != new_carrier)) {
1208 if (!new_carrier) { 1208 if (!new_carrier) {
@@ -1224,11 +1224,11 @@ static void smc_eph_interrupt(struct net_device *dev)
1224 1224
1225 smc_10bt_check_media(dev, 0); 1225 smc_10bt_check_media(dev, 0);
1226 1226
1227 SMC_SELECT_BANK(1); 1227 SMC_SELECT_BANK(lp, 1);
1228 ctl = SMC_GET_CTL(); 1228 ctl = SMC_GET_CTL(lp);
1229 SMC_SET_CTL(ctl & ~CTL_LE_ENABLE); 1229 SMC_SET_CTL(lp, ctl & ~CTL_LE_ENABLE);
1230 SMC_SET_CTL(ctl); 1230 SMC_SET_CTL(lp, ctl);
1231 SMC_SELECT_BANK(2); 1231 SMC_SELECT_BANK(lp, 2);
1232} 1232}
1233 1233
1234/* 1234/*
@@ -1252,22 +1252,22 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
1252 * ISR. */ 1252 * ISR. */
1253 SMC_INTERRUPT_PREAMBLE; 1253 SMC_INTERRUPT_PREAMBLE;
1254 1254
1255 saved_pointer = SMC_GET_PTR(); 1255 saved_pointer = SMC_GET_PTR(lp);
1256 mask = SMC_GET_INT_MASK(); 1256 mask = SMC_GET_INT_MASK(lp);
1257 SMC_SET_INT_MASK(0); 1257 SMC_SET_INT_MASK(lp, 0);
1258 1258
1259 /* set a timeout value, so I don't stay here forever */ 1259 /* set a timeout value, so I don't stay here forever */
1260 timeout = MAX_IRQ_LOOPS; 1260 timeout = MAX_IRQ_LOOPS;
1261 1261
1262 do { 1262 do {
1263 status = SMC_GET_INT(); 1263 status = SMC_GET_INT(lp);
1264 1264
1265 DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", 1265 DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
1266 dev->name, status, mask, 1266 dev->name, status, mask,
1267 ({ int meminfo; SMC_SELECT_BANK(0); 1267 ({ int meminfo; SMC_SELECT_BANK(lp, 0);
1268 meminfo = SMC_GET_MIR(); 1268 meminfo = SMC_GET_MIR(lp);
1269 SMC_SELECT_BANK(2); meminfo; }), 1269 SMC_SELECT_BANK(lp, 2); meminfo; }),
1270 SMC_GET_FIFO()); 1270 SMC_GET_FIFO(lp));
1271 1271
1272 status &= mask; 1272 status &= mask;
1273 if (!status) 1273 if (!status)
@@ -1277,7 +1277,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
1277 /* do this before RX as it will free memory quickly */ 1277 /* do this before RX as it will free memory quickly */
1278 DBG(3, "%s: TX int\n", dev->name); 1278 DBG(3, "%s: TX int\n", dev->name);
1279 smc_tx(dev); 1279 smc_tx(dev);
1280 SMC_ACK_INT(IM_TX_INT); 1280 SMC_ACK_INT(lp, IM_TX_INT);
1281 if (THROTTLE_TX_PKTS) 1281 if (THROTTLE_TX_PKTS)
1282 netif_wake_queue(dev); 1282 netif_wake_queue(dev);
1283 } else if (status & IM_RCV_INT) { 1283 } else if (status & IM_RCV_INT) {
@@ -1292,9 +1292,9 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
1292 mask &= ~IM_TX_EMPTY_INT; 1292 mask &= ~IM_TX_EMPTY_INT;
1293 1293
1294 /* update stats */ 1294 /* update stats */
1295 SMC_SELECT_BANK(0); 1295 SMC_SELECT_BANK(lp, 0);
1296 card_stats = SMC_GET_COUNTER(); 1296 card_stats = SMC_GET_COUNTER(lp);
1297 SMC_SELECT_BANK(2); 1297 SMC_SELECT_BANK(lp, 2);
1298 1298
1299 /* single collisions */ 1299 /* single collisions */
1300 dev->stats.collisions += card_stats & 0xF; 1300 dev->stats.collisions += card_stats & 0xF;
@@ -1304,26 +1304,26 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
1304 dev->stats.collisions += card_stats & 0xF; 1304 dev->stats.collisions += card_stats & 0xF;
1305 } else if (status & IM_RX_OVRN_INT) { 1305 } else if (status & IM_RX_OVRN_INT) {
1306 DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, 1306 DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
1307 ({ int eph_st; SMC_SELECT_BANK(0); 1307 ({ int eph_st; SMC_SELECT_BANK(lp, 0);
1308 eph_st = SMC_GET_EPH_STATUS(); 1308 eph_st = SMC_GET_EPH_STATUS(lp);
1309 SMC_SELECT_BANK(2); eph_st; }) ); 1309 SMC_SELECT_BANK(lp, 2); eph_st; }));
1310 SMC_ACK_INT(IM_RX_OVRN_INT); 1310 SMC_ACK_INT(lp, IM_RX_OVRN_INT);
1311 dev->stats.rx_errors++; 1311 dev->stats.rx_errors++;
1312 dev->stats.rx_fifo_errors++; 1312 dev->stats.rx_fifo_errors++;
1313 } else if (status & IM_EPH_INT) { 1313 } else if (status & IM_EPH_INT) {
1314 smc_eph_interrupt(dev); 1314 smc_eph_interrupt(dev);
1315 } else if (status & IM_MDINT) { 1315 } else if (status & IM_MDINT) {
1316 SMC_ACK_INT(IM_MDINT); 1316 SMC_ACK_INT(lp, IM_MDINT);
1317 smc_phy_interrupt(dev); 1317 smc_phy_interrupt(dev);
1318 } else if (status & IM_ERCV_INT) { 1318 } else if (status & IM_ERCV_INT) {
1319 SMC_ACK_INT(IM_ERCV_INT); 1319 SMC_ACK_INT(lp, IM_ERCV_INT);
1320 PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name); 1320 PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name);
1321 } 1321 }
1322 } while (--timeout); 1322 } while (--timeout);
1323 1323
1324 /* restore register states */ 1324 /* restore register states */
1325 SMC_SET_PTR(saved_pointer); 1325 SMC_SET_PTR(lp, saved_pointer);
1326 SMC_SET_INT_MASK(mask); 1326 SMC_SET_INT_MASK(lp, mask);
1327 spin_unlock(&lp->lock); 1327 spin_unlock(&lp->lock);
1328 1328
1329 if (timeout == MAX_IRQ_LOOPS) 1329 if (timeout == MAX_IRQ_LOOPS)
@@ -1366,13 +1366,13 @@ static void smc_timeout(struct net_device *dev)
1366 DBG(2, "%s: %s\n", dev->name, __FUNCTION__); 1366 DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
1367 1367
1368 spin_lock_irq(&lp->lock); 1368 spin_lock_irq(&lp->lock);
1369 status = SMC_GET_INT(); 1369 status = SMC_GET_INT(lp);
1370 mask = SMC_GET_INT_MASK(); 1370 mask = SMC_GET_INT_MASK(lp);
1371 fifo = SMC_GET_FIFO(); 1371 fifo = SMC_GET_FIFO(lp);
1372 SMC_SELECT_BANK(0); 1372 SMC_SELECT_BANK(lp, 0);
1373 eph_st = SMC_GET_EPH_STATUS(); 1373 eph_st = SMC_GET_EPH_STATUS(lp);
1374 meminfo = SMC_GET_MIR(); 1374 meminfo = SMC_GET_MIR(lp);
1375 SMC_SELECT_BANK(2); 1375 SMC_SELECT_BANK(lp, 2);
1376 spin_unlock_irq(&lp->lock); 1376 spin_unlock_irq(&lp->lock);
1377 PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x " 1377 PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x "
1378 "MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n", 1378 "MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n",
@@ -1492,13 +1492,13 @@ static void smc_set_multicast_list(struct net_device *dev)
1492 } 1492 }
1493 1493
1494 spin_lock_irq(&lp->lock); 1494 spin_lock_irq(&lp->lock);
1495 SMC_SELECT_BANK(0); 1495 SMC_SELECT_BANK(lp, 0);
1496 SMC_SET_RCR(lp->rcr_cur_mode); 1496 SMC_SET_RCR(lp, lp->rcr_cur_mode);
1497 if (update_multicast) { 1497 if (update_multicast) {
1498 SMC_SELECT_BANK(3); 1498 SMC_SELECT_BANK(lp, 3);
1499 SMC_SET_MCAST(multicast_table); 1499 SMC_SET_MCAST(lp, multicast_table);
1500 } 1500 }
1501 SMC_SELECT_BANK(2); 1501 SMC_SELECT_BANK(lp, 2);
1502 spin_unlock_irq(&lp->lock); 1502 spin_unlock_irq(&lp->lock);
1503} 1503}
1504 1504
@@ -1702,8 +1702,9 @@ static const struct ethtool_ops smc_ethtool_ops = {
1702 * I just deleted auto_irq.c, since it was never built... 1702 * I just deleted auto_irq.c, since it was never built...
1703 * --jgarzik 1703 * --jgarzik
1704 */ 1704 */
1705static int __init smc_findirq(void __iomem *ioaddr) 1705static int __init smc_findirq(struct smc_local *lp)
1706{ 1706{
1707 void __iomem *ioaddr = lp->base;
1707 int timeout = 20; 1708 int timeout = 20;
1708 unsigned long cookie; 1709 unsigned long cookie;
1709 1710
@@ -1717,14 +1718,14 @@ static int __init smc_findirq(void __iomem *ioaddr)
1717 * when done. 1718 * when done.
1718 */ 1719 */
1719 /* enable ALLOCation interrupts ONLY */ 1720 /* enable ALLOCation interrupts ONLY */
1720 SMC_SELECT_BANK(2); 1721 SMC_SELECT_BANK(lp, 2);
1721 SMC_SET_INT_MASK(IM_ALLOC_INT); 1722 SMC_SET_INT_MASK(lp, IM_ALLOC_INT);
1722 1723
1723 /* 1724 /*
1724 * Allocate 512 bytes of memory. Note that the chip was just 1725 * Allocate 512 bytes of memory. Note that the chip was just
1725 * reset so all the memory is available 1726 * reset so all the memory is available
1726 */ 1727 */
1727 SMC_SET_MMU_CMD(MC_ALLOC | 1); 1728 SMC_SET_MMU_CMD(lp, MC_ALLOC | 1);
1728 1729
1729 /* 1730 /*
1730 * Wait until positive that the interrupt has been generated 1731 * Wait until positive that the interrupt has been generated
@@ -1732,7 +1733,7 @@ static int __init smc_findirq(void __iomem *ioaddr)
1732 do { 1733 do {
1733 int int_status; 1734 int int_status;
1734 udelay(10); 1735 udelay(10);
1735 int_status = SMC_GET_INT(); 1736 int_status = SMC_GET_INT(lp);
1736 if (int_status & IM_ALLOC_INT) 1737 if (int_status & IM_ALLOC_INT)
1737 break; /* got the interrupt */ 1738 break; /* got the interrupt */
1738 } while (--timeout); 1739 } while (--timeout);
@@ -1745,7 +1746,7 @@ static int __init smc_findirq(void __iomem *ioaddr)
1745 */ 1746 */
1746 1747
1747 /* and disable all interrupts again */ 1748 /* and disable all interrupts again */
1748 SMC_SET_INT_MASK(0); 1749 SMC_SET_INT_MASK(lp, 0);
1749 1750
1750 /* and return what I found */ 1751 /* and return what I found */
1751 return probe_irq_off(cookie); 1752 return probe_irq_off(cookie);
@@ -1788,7 +1789,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
1788 DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); 1789 DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
1789 1790
1790 /* First, see if the high byte is 0x33 */ 1791 /* First, see if the high byte is 0x33 */
1791 val = SMC_CURRENT_BANK(); 1792 val = SMC_CURRENT_BANK(lp);
1792 DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val); 1793 DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val);
1793 if ((val & 0xFF00) != 0x3300) { 1794 if ((val & 0xFF00) != 0x3300) {
1794 if ((val & 0xFF) == 0x33) { 1795 if ((val & 0xFF) == 0x33) {
@@ -1804,8 +1805,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
1804 * The above MIGHT indicate a device, but I need to write to 1805 * The above MIGHT indicate a device, but I need to write to
1805 * further test this. 1806 * further test this.
1806 */ 1807 */
1807 SMC_SELECT_BANK(0); 1808 SMC_SELECT_BANK(lp, 0);
1808 val = SMC_CURRENT_BANK(); 1809 val = SMC_CURRENT_BANK(lp);
1809 if ((val & 0xFF00) != 0x3300) { 1810 if ((val & 0xFF00) != 0x3300) {
1810 retval = -ENODEV; 1811 retval = -ENODEV;
1811 goto err_out; 1812 goto err_out;
@@ -1817,8 +1818,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
1817 * register to bank 1, so I can access the base address 1818 * register to bank 1, so I can access the base address
1818 * register 1819 * register
1819 */ 1820 */
1820 SMC_SELECT_BANK(1); 1821 SMC_SELECT_BANK(lp, 1);
1821 val = SMC_GET_BASE(); 1822 val = SMC_GET_BASE(lp);
1822 val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; 1823 val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
1823 if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { 1824 if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
1824 printk("%s: IOADDR %p doesn't match configuration (%x).\n", 1825 printk("%s: IOADDR %p doesn't match configuration (%x).\n",
@@ -1830,8 +1831,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
1830 * recognize. These might need to be added to later, 1831 * recognize. These might need to be added to later,
1831 * as future revisions could be added. 1832 * as future revisions could be added.
1832 */ 1833 */
1833 SMC_SELECT_BANK(3); 1834 SMC_SELECT_BANK(lp, 3);
1834 revision_register = SMC_GET_REV(); 1835 revision_register = SMC_GET_REV(lp);
1835 DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register); 1836 DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register);
1836 version_string = chip_ids[ (revision_register >> 4) & 0xF]; 1837 version_string = chip_ids[ (revision_register >> 4) & 0xF];
1837 if (!version_string || (revision_register & 0xff00) != 0x3300) { 1838 if (!version_string || (revision_register & 0xff00) != 0x3300) {
@@ -1855,8 +1856,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
1855 spin_lock_init(&lp->lock); 1856 spin_lock_init(&lp->lock);
1856 1857
1857 /* Get the MAC address */ 1858 /* Get the MAC address */
1858 SMC_SELECT_BANK(1); 1859 SMC_SELECT_BANK(lp, 1);
1859 SMC_GET_MAC_ADDR(dev->dev_addr); 1860 SMC_GET_MAC_ADDR(lp, dev->dev_addr);
1860 1861
1861 /* now, reset the chip, and put it into a known state */ 1862 /* now, reset the chip, and put it into a known state */
1862 smc_reset(dev); 1863 smc_reset(dev);
@@ -1881,7 +1882,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
1881 1882
1882 trials = 3; 1883 trials = 3;
1883 while (trials--) { 1884 while (trials--) {
1884 dev->irq = smc_findirq(ioaddr); 1885 dev->irq = smc_findirq(lp);
1885 if (dev->irq) 1886 if (dev->irq)
1886 break; 1887 break;
1887 /* kick the card and try again */ 1888 /* kick the card and try again */
@@ -1996,6 +1997,8 @@ err_out:
1996 1997
1997static int smc_enable_device(struct platform_device *pdev) 1998static int smc_enable_device(struct platform_device *pdev)
1998{ 1999{
2000 struct net_device *ndev = platform_get_drvdata(pdev);
2001 struct smc_local *lp = netdev_priv(ndev);
1999 unsigned long flags; 2002 unsigned long flags;
2000 unsigned char ecor, ecsr; 2003 unsigned char ecor, ecsr;
2001 void __iomem *addr; 2004 void __iomem *addr;
@@ -2038,7 +2041,7 @@ static int smc_enable_device(struct platform_device *pdev)
2038 * Set the appropriate byte/word mode. 2041 * Set the appropriate byte/word mode.
2039 */ 2042 */
2040 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; 2043 ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8;
2041 if (!SMC_CAN_USE_16BIT) 2044 if (!SMC_16BIT(lp))
2042 ecsr |= ECSR_IOIS8; 2045 ecsr |= ECSR_IOIS8;
2043 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); 2046 writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT));
2044 local_irq_restore(flags); 2047 local_irq_restore(flags);
@@ -2123,10 +2126,11 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
2123 */ 2126 */
2124static int smc_drv_probe(struct platform_device *pdev) 2127static int smc_drv_probe(struct platform_device *pdev)
2125{ 2128{
2129 struct smc91x_platdata *pd = pdev->dev.platform_data;
2130 struct smc_local *lp;
2126 struct net_device *ndev; 2131 struct net_device *ndev;
2127 struct resource *res, *ires; 2132 struct resource *res, *ires;
2128 unsigned int __iomem *addr; 2133 unsigned int __iomem *addr;
2129 unsigned long irq_flags = SMC_IRQ_FLAGS;
2130 int ret; 2134 int ret;
2131 2135
2132 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); 2136 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
@@ -2151,6 +2155,27 @@ static int smc_drv_probe(struct platform_device *pdev)
2151 } 2155 }
2152 SET_NETDEV_DEV(ndev, &pdev->dev); 2156 SET_NETDEV_DEV(ndev, &pdev->dev);
2153 2157
2158 /* get configuration from platform data, only allow use of
2159 * bus width if both SMC_CAN_USE_xxx and SMC91X_USE_xxx are set.
2160 */
2161
2162 lp = netdev_priv(ndev);
2163 lp->cfg.irq_flags = SMC_IRQ_FLAGS;
2164
2165#ifdef SMC_DYNAMIC_BUS_CONFIG
2166 if (pd)
2167 memcpy(&lp->cfg, pd, sizeof(lp->cfg));
2168 else {
2169 lp->cfg.flags = SMC91X_USE_8BIT;
2170 lp->cfg.flags |= SMC91X_USE_16BIT;
2171 lp->cfg.flags |= SMC91X_USE_32BIT;
2172 }
2173
2174 lp->cfg.flags &= ~(SMC_CAN_USE_8BIT ? 0 : SMC91X_USE_8BIT);
2175 lp->cfg.flags &= ~(SMC_CAN_USE_16BIT ? 0 : SMC91X_USE_16BIT);
2176 lp->cfg.flags &= ~(SMC_CAN_USE_32BIT ? 0 : SMC91X_USE_32BIT);
2177#endif
2178
2154 ndev->dma = (unsigned char)-1; 2179 ndev->dma = (unsigned char)-1;
2155 2180
2156 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 2181 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -2161,7 +2186,7 @@ static int smc_drv_probe(struct platform_device *pdev)
2161 2186
2162 ndev->irq = ires->start; 2187 ndev->irq = ires->start;
2163 if (SMC_IRQ_FLAGS == -1) 2188 if (SMC_IRQ_FLAGS == -1)
2164 irq_flags = ires->flags & IRQF_TRIGGER_MASK; 2189 lp->cfg.irq_flags = ires->flags & IRQF_TRIGGER_MASK;
2165 2190
2166 ret = smc_request_attrib(pdev); 2191 ret = smc_request_attrib(pdev);
2167 if (ret) 2192 if (ret)
@@ -2169,6 +2194,7 @@ static int smc_drv_probe(struct platform_device *pdev)
2169#if defined(CONFIG_SA1100_ASSABET) 2194#if defined(CONFIG_SA1100_ASSABET)
2170 NCR_0 |= NCR_ENET_OSC_EN; 2195 NCR_0 |= NCR_ENET_OSC_EN;
2171#endif 2196#endif
2197 platform_set_drvdata(pdev, ndev);
2172 ret = smc_enable_device(pdev); 2198 ret = smc_enable_device(pdev);
2173 if (ret) 2199 if (ret)
2174 goto out_release_attrib; 2200 goto out_release_attrib;
@@ -2187,8 +2213,7 @@ static int smc_drv_probe(struct platform_device *pdev)
2187 } 2213 }
2188#endif 2214#endif
2189 2215
2190 platform_set_drvdata(pdev, ndev); 2216 ret = smc_probe(ndev, addr, lp->cfg.irq_flags);
2191 ret = smc_probe(ndev, addr, irq_flags);
2192 if (ret != 0) 2217 if (ret != 0)
2193 goto out_iounmap; 2218 goto out_iounmap;
2194 2219
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 51d4134b37b1..69e97a1cb1c4 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -34,6 +34,7 @@
34#ifndef _SMC91X_H_ 34#ifndef _SMC91X_H_
35#define _SMC91X_H_ 35#define _SMC91X_H_
36 36
37#include <linux/smc91x.h>
37 38
38/* 39/*
39 * Define your architecture specific bus configuration parameters here. 40 * Define your architecture specific bus configuration parameters here.
@@ -291,36 +292,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
291#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) 292#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
292#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) 293#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
293 294
294#elif defined(CONFIG_SUPERH)
295
296#ifdef CONFIG_SOLUTION_ENGINE
297#define SMC_IRQ_FLAGS (0)
298#define SMC_CAN_USE_8BIT 0
299#define SMC_CAN_USE_16BIT 1
300#define SMC_CAN_USE_32BIT 0
301#define SMC_IO_SHIFT 0
302#define SMC_NOWAIT 1
303
304#define SMC_inw(a, r) inw((a) + (r))
305#define SMC_outw(v, a, r) outw(v, (a) + (r))
306#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
307#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
308
309#else /* BOARDS */
310
311#define SMC_CAN_USE_8BIT 1
312#define SMC_CAN_USE_16BIT 1
313#define SMC_CAN_USE_32BIT 0
314
315#define SMC_inb(a, r) inb((a) + (r))
316#define SMC_inw(a, r) inw((a) + (r))
317#define SMC_outb(v, a, r) outb(v, (a) + (r))
318#define SMC_outw(v, a, r) outw(v, (a) + (r))
319#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
320#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
321
322#endif /* BOARDS */
323
324#elif defined(CONFIG_M32R) 295#elif defined(CONFIG_M32R)
325 296
326#define SMC_CAN_USE_8BIT 0 297#define SMC_CAN_USE_8BIT 0
@@ -475,12 +446,15 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
475#define SMC_outb(v, a, r) writeb(v, (a) + (r)) 446#define SMC_outb(v, a, r) writeb(v, (a) + (r))
476#define SMC_outw(v, a, r) writew(v, (a) + (r)) 447#define SMC_outw(v, a, r) writew(v, (a) + (r))
477#define SMC_outl(v, a, r) writel(v, (a) + (r)) 448#define SMC_outl(v, a, r) writel(v, (a) + (r))
449#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
450#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
478#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) 451#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
479#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) 452#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
480 453
481#define RPC_LSA_DEFAULT RPC_LED_100_10 454#define RPC_LSA_DEFAULT RPC_LED_100_10
482#define RPC_LSB_DEFAULT RPC_LED_TX_RX 455#define RPC_LSB_DEFAULT RPC_LED_TX_RX
483 456
457#define SMC_DYNAMIC_BUS_CONFIG
484#endif 458#endif
485 459
486 460
@@ -526,8 +500,19 @@ struct smc_local {
526#endif 500#endif
527 void __iomem *base; 501 void __iomem *base;
528 void __iomem *datacs; 502 void __iomem *datacs;
503
504 struct smc91x_platdata cfg;
529}; 505};
530 506
507#ifdef SMC_DYNAMIC_BUS_CONFIG
508#define SMC_8BIT(p) (((p)->cfg.flags & SMC91X_USE_8BIT) && SMC_CAN_USE_8BIT)
509#define SMC_16BIT(p) (((p)->cfg.flags & SMC91X_USE_16BIT) && SMC_CAN_USE_16BIT)
510#define SMC_32BIT(p) (((p)->cfg.flags & SMC91X_USE_32BIT) && SMC_CAN_USE_32BIT)
511#else
512#define SMC_8BIT(p) SMC_CAN_USE_8BIT
513#define SMC_16BIT(p) SMC_CAN_USE_16BIT
514#define SMC_32BIT(p) SMC_CAN_USE_32BIT
515#endif
531 516
532#ifdef SMC_USE_PXA_DMA 517#ifdef SMC_USE_PXA_DMA
533/* 518/*
@@ -720,7 +705,7 @@ smc_pxa_dma_irq(int dma, void *dummy)
720 705
721// Transmit Control Register 706// Transmit Control Register
722/* BANK 0 */ 707/* BANK 0 */
723#define TCR_REG SMC_REG(0x0000, 0) 708#define TCR_REG(lp) SMC_REG(lp, 0x0000, 0)
724#define TCR_ENABLE 0x0001 // When 1 we can transmit 709#define TCR_ENABLE 0x0001 // When 1 we can transmit
725#define TCR_LOOP 0x0002 // Controls output pin LBK 710#define TCR_LOOP 0x0002 // Controls output pin LBK
726#define TCR_FORCOL 0x0004 // When 1 will force a collision 711#define TCR_FORCOL 0x0004 // When 1 will force a collision
@@ -739,7 +724,7 @@ smc_pxa_dma_irq(int dma, void *dummy)
739 724
740// EPH Status Register 725// EPH Status Register
741/* BANK 0 */ 726/* BANK 0 */
742#define EPH_STATUS_REG SMC_REG(0x0002, 0) 727#define EPH_STATUS_REG(lp) SMC_REG(lp, 0x0002, 0)
743#define ES_TX_SUC 0x0001 // Last TX was successful 728#define ES_TX_SUC 0x0001 // Last TX was successful
744#define ES_SNGL_COL 0x0002 // Single collision detected for last tx 729#define ES_SNGL_COL 0x0002 // Single collision detected for last tx
745#define ES_MUL_COL 0x0004 // Multiple collisions detected for last tx 730#define ES_MUL_COL 0x0004 // Multiple collisions detected for last tx
@@ -758,7 +743,7 @@ smc_pxa_dma_irq(int dma, void *dummy)
758 743
759// Receive Control Register 744// Receive Control Register
760/* BANK 0 */ 745/* BANK 0 */
761#define RCR_REG SMC_REG(0x0004, 0) 746#define RCR_REG(lp) SMC_REG(lp, 0x0004, 0)
762#define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted 747#define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted
763#define RCR_PRMS 0x0002 // Enable promiscuous mode 748#define RCR_PRMS 0x0002 // Enable promiscuous mode
764#define RCR_ALMUL 0x0004 // When set accepts all multicast frames 749#define RCR_ALMUL 0x0004 // When set accepts all multicast frames
@@ -775,17 +760,17 @@ smc_pxa_dma_irq(int dma, void *dummy)
775 760
776// Counter Register 761// Counter Register
777/* BANK 0 */ 762/* BANK 0 */
778#define COUNTER_REG SMC_REG(0x0006, 0) 763#define COUNTER_REG(lp) SMC_REG(lp, 0x0006, 0)
779 764
780 765
781// Memory Information Register 766// Memory Information Register
782/* BANK 0 */ 767/* BANK 0 */
783#define MIR_REG SMC_REG(0x0008, 0) 768#define MIR_REG(lp) SMC_REG(lp, 0x0008, 0)
784 769
785 770
786// Receive/Phy Control Register 771// Receive/Phy Control Register
787/* BANK 0 */ 772/* BANK 0 */
788#define RPC_REG SMC_REG(0x000A, 0) 773#define RPC_REG(lp) SMC_REG(lp, 0x000A, 0)
789#define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. 774#define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode.
790#define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode 775#define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode
791#define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode 776#define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode
@@ -819,7 +804,7 @@ smc_pxa_dma_irq(int dma, void *dummy)
819 804
820// Configuration Reg 805// Configuration Reg
821/* BANK 1 */ 806/* BANK 1 */
822#define CONFIG_REG SMC_REG(0x0000, 1) 807#define CONFIG_REG(lp) SMC_REG(lp, 0x0000, 1)
823#define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy 808#define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy
824#define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL 809#define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL
825#define CONFIG_NO_WAIT 0x1000 // When 1 no extra wait states on ISA bus 810#define CONFIG_NO_WAIT 0x1000 // When 1 no extra wait states on ISA bus
@@ -831,24 +816,24 @@ smc_pxa_dma_irq(int dma, void *dummy)
831 816
832// Base Address Register 817// Base Address Register
833/* BANK 1 */ 818/* BANK 1 */
834#define BASE_REG SMC_REG(0x0002, 1) 819#define BASE_REG(lp) SMC_REG(lp, 0x0002, 1)
835 820
836 821
837// Individual Address Registers 822// Individual Address Registers
838/* BANK 1 */ 823/* BANK 1 */
839#define ADDR0_REG SMC_REG(0x0004, 1) 824#define ADDR0_REG(lp) SMC_REG(lp, 0x0004, 1)
840#define ADDR1_REG SMC_REG(0x0006, 1) 825#define ADDR1_REG(lp) SMC_REG(lp, 0x0006, 1)
841#define ADDR2_REG SMC_REG(0x0008, 1) 826#define ADDR2_REG(lp) SMC_REG(lp, 0x0008, 1)
842 827
843 828
844// General Purpose Register 829// General Purpose Register
845/* BANK 1 */ 830/* BANK 1 */
846#define GP_REG SMC_REG(0x000A, 1) 831#define GP_REG(lp) SMC_REG(lp, 0x000A, 1)
847 832
848 833
849// Control Register 834// Control Register
850/* BANK 1 */ 835/* BANK 1 */
851#define CTL_REG SMC_REG(0x000C, 1) 836#define CTL_REG(lp) SMC_REG(lp, 0x000C, 1)
852#define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received 837#define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received
853#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically 838#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically
854#define CTL_LE_ENABLE 0x0080 // When 1 enables Link Error interrupt 839#define CTL_LE_ENABLE 0x0080 // When 1 enables Link Error interrupt
@@ -861,7 +846,7 @@ smc_pxa_dma_irq(int dma, void *dummy)
861 846
862// MMU Command Register 847// MMU Command Register
863/* BANK 2 */ 848/* BANK 2 */
864#define MMU_CMD_REG SMC_REG(0x0000, 2) 849#define MMU_CMD_REG(lp) SMC_REG(lp, 0x0000, 2)
865#define MC_BUSY 1 // When 1 the last release has not completed 850#define MC_BUSY 1 // When 1 the last release has not completed
866#define MC_NOP (0<<5) // No Op 851#define MC_NOP (0<<5) // No Op
867#define MC_ALLOC (1<<5) // OR with number of 256 byte packets 852#define MC_ALLOC (1<<5) // OR with number of 256 byte packets
@@ -875,30 +860,30 @@ smc_pxa_dma_irq(int dma, void *dummy)
875 860
876// Packet Number Register 861// Packet Number Register
877/* BANK 2 */ 862/* BANK 2 */
878#define PN_REG SMC_REG(0x0002, 2) 863#define PN_REG(lp) SMC_REG(lp, 0x0002, 2)
879 864
880 865
881// Allocation Result Register 866// Allocation Result Register
882/* BANK 2 */ 867/* BANK 2 */
883#define AR_REG SMC_REG(0x0003, 2) 868#define AR_REG(lp) SMC_REG(lp, 0x0003, 2)
884#define AR_FAILED 0x80 // Alocation Failed 869#define AR_FAILED 0x80 // Alocation Failed
885 870
886 871
887// TX FIFO Ports Register 872// TX FIFO Ports Register
888/* BANK 2 */ 873/* BANK 2 */
889#define TXFIFO_REG SMC_REG(0x0004, 2) 874#define TXFIFO_REG(lp) SMC_REG(lp, 0x0004, 2)
890#define TXFIFO_TEMPTY 0x80 // TX FIFO Empty 875#define TXFIFO_TEMPTY 0x80 // TX FIFO Empty
891 876
892// RX FIFO Ports Register 877// RX FIFO Ports Register
893/* BANK 2 */ 878/* BANK 2 */
894#define RXFIFO_REG SMC_REG(0x0005, 2) 879#define RXFIFO_REG(lp) SMC_REG(lp, 0x0005, 2)
895#define RXFIFO_REMPTY 0x80 // RX FIFO Empty 880#define RXFIFO_REMPTY 0x80 // RX FIFO Empty
896 881
897#define FIFO_REG SMC_REG(0x0004, 2) 882#define FIFO_REG(lp) SMC_REG(lp, 0x0004, 2)
898 883
899// Pointer Register 884// Pointer Register
900/* BANK 2 */ 885/* BANK 2 */
901#define PTR_REG SMC_REG(0x0006, 2) 886#define PTR_REG(lp) SMC_REG(lp, 0x0006, 2)
902#define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area 887#define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area
903#define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access 888#define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access
904#define PTR_READ 0x2000 // When 1 the operation is a read 889#define PTR_READ 0x2000 // When 1 the operation is a read
@@ -906,17 +891,17 @@ smc_pxa_dma_irq(int dma, void *dummy)
906 891
907// Data Register 892// Data Register
908/* BANK 2 */ 893/* BANK 2 */
909#define DATA_REG SMC_REG(0x0008, 2) 894#define DATA_REG(lp) SMC_REG(lp, 0x0008, 2)
910 895
911 896
912// Interrupt Status/Acknowledge Register 897// Interrupt Status/Acknowledge Register
913/* BANK 2 */ 898/* BANK 2 */
914#define INT_REG SMC_REG(0x000C, 2) 899#define INT_REG(lp) SMC_REG(lp, 0x000C, 2)
915 900
916 901
917// Interrupt Mask Register 902// Interrupt Mask Register
918/* BANK 2 */ 903/* BANK 2 */
919#define IM_REG SMC_REG(0x000D, 2) 904#define IM_REG(lp) SMC_REG(lp, 0x000D, 2)
920#define IM_MDINT 0x80 // PHY MI Register 18 Interrupt 905#define IM_MDINT 0x80 // PHY MI Register 18 Interrupt
921#define IM_ERCV_INT 0x40 // Early Receive Interrupt 906#define IM_ERCV_INT 0x40 // Early Receive Interrupt
922#define IM_EPH_INT 0x20 // Set by Ethernet Protocol Handler section 907#define IM_EPH_INT 0x20 // Set by Ethernet Protocol Handler section
@@ -929,15 +914,15 @@ smc_pxa_dma_irq(int dma, void *dummy)
929 914
930// Multicast Table Registers 915// Multicast Table Registers
931/* BANK 3 */ 916/* BANK 3 */
932#define MCAST_REG1 SMC_REG(0x0000, 3) 917#define MCAST_REG1(lp) SMC_REG(lp, 0x0000, 3)
933#define MCAST_REG2 SMC_REG(0x0002, 3) 918#define MCAST_REG2(lp) SMC_REG(lp, 0x0002, 3)
934#define MCAST_REG3 SMC_REG(0x0004, 3) 919#define MCAST_REG3(lp) SMC_REG(lp, 0x0004, 3)
935#define MCAST_REG4 SMC_REG(0x0006, 3) 920#define MCAST_REG4(lp) SMC_REG(lp, 0x0006, 3)
936 921
937 922
938// Management Interface Register (MII) 923// Management Interface Register (MII)
939/* BANK 3 */ 924/* BANK 3 */
940#define MII_REG SMC_REG(0x0008, 3) 925#define MII_REG(lp) SMC_REG(lp, 0x0008, 3)
941#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup 926#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup
942#define MII_MDOE 0x0008 // MII Output Enable 927#define MII_MDOE 0x0008 // MII Output Enable
943#define MII_MCLK 0x0004 // MII Clock, pin MDCLK 928#define MII_MCLK 0x0004 // MII Clock, pin MDCLK
@@ -948,20 +933,20 @@ smc_pxa_dma_irq(int dma, void *dummy)
948// Revision Register 933// Revision Register
949/* BANK 3 */ 934/* BANK 3 */
950/* ( hi: chip id low: rev # ) */ 935/* ( hi: chip id low: rev # ) */
951#define REV_REG SMC_REG(0x000A, 3) 936#define REV_REG(lp) SMC_REG(lp, 0x000A, 3)
952 937
953 938
954// Early RCV Register 939// Early RCV Register
955/* BANK 3 */ 940/* BANK 3 */
956/* this is NOT on SMC9192 */ 941/* this is NOT on SMC9192 */
957#define ERCV_REG SMC_REG(0x000C, 3) 942#define ERCV_REG(lp) SMC_REG(lp, 0x000C, 3)
958#define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received 943#define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received
959#define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask 944#define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask
960 945
961 946
962// External Register 947// External Register
963/* BANK 7 */ 948/* BANK 7 */
964#define EXT_REG SMC_REG(0x0000, 7) 949#define EXT_REG(lp) SMC_REG(lp, 0x0000, 7)
965 950
966 951
967#define CHIP_9192 3 952#define CHIP_9192 3
@@ -1085,9 +1070,9 @@ static const char * chip_ids[ 16 ] = {
1085 */ 1070 */
1086 1071
1087#if SMC_DEBUG > 0 1072#if SMC_DEBUG > 0
1088#define SMC_REG(reg, bank) \ 1073#define SMC_REG(lp, reg, bank) \
1089 ({ \ 1074 ({ \
1090 int __b = SMC_CURRENT_BANK(); \ 1075 int __b = SMC_CURRENT_BANK(lp); \
1091 if (unlikely((__b & ~0xf0) != (0x3300 | bank))) { \ 1076 if (unlikely((__b & ~0xf0) != (0x3300 | bank))) { \
1092 printk( "%s: bank reg screwed (0x%04x)\n", \ 1077 printk( "%s: bank reg screwed (0x%04x)\n", \
1093 CARDNAME, __b ); \ 1078 CARDNAME, __b ); \
@@ -1096,7 +1081,7 @@ static const char * chip_ids[ 16 ] = {
1096 reg<<SMC_IO_SHIFT; \ 1081 reg<<SMC_IO_SHIFT; \
1097 }) 1082 })
1098#else 1083#else
1099#define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT) 1084#define SMC_REG(lp, reg, bank) (reg<<SMC_IO_SHIFT)
1100#endif 1085#endif
1101 1086
1102/* 1087/*
@@ -1108,212 +1093,215 @@ static const char * chip_ids[ 16 ] = {
1108 * 1093 *
1109 * Enforce it on any 32-bit capable setup for now. 1094 * Enforce it on any 32-bit capable setup for now.
1110 */ 1095 */
1111#define SMC_MUST_ALIGN_WRITE SMC_CAN_USE_32BIT 1096#define SMC_MUST_ALIGN_WRITE(lp) SMC_32BIT(lp)
1112 1097
1113#define SMC_GET_PN() \ 1098#define SMC_GET_PN(lp) \
1114 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, PN_REG)) \ 1099 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, PN_REG(lp))) \
1115 : (SMC_inw(ioaddr, PN_REG) & 0xFF) ) 1100 : (SMC_inw(ioaddr, PN_REG(lp)) & 0xFF))
1116 1101
1117#define SMC_SET_PN(x) \ 1102#define SMC_SET_PN(lp, x) \
1118 do { \ 1103 do { \
1119 if (SMC_MUST_ALIGN_WRITE) \ 1104 if (SMC_MUST_ALIGN_WRITE(lp)) \
1120 SMC_outl((x)<<16, ioaddr, SMC_REG(0, 2)); \ 1105 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 0, 2)); \
1121 else if (SMC_CAN_USE_8BIT) \ 1106 else if (SMC_8BIT(lp)) \
1122 SMC_outb(x, ioaddr, PN_REG); \ 1107 SMC_outb(x, ioaddr, PN_REG(lp)); \
1123 else \ 1108 else \
1124 SMC_outw(x, ioaddr, PN_REG); \ 1109 SMC_outw(x, ioaddr, PN_REG(lp)); \
1125 } while (0) 1110 } while (0)
1126 1111
1127#define SMC_GET_AR() \ 1112#define SMC_GET_AR(lp) \
1128 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, AR_REG)) \ 1113 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, AR_REG(lp))) \
1129 : (SMC_inw(ioaddr, PN_REG) >> 8) ) 1114 : (SMC_inw(ioaddr, PN_REG(lp)) >> 8))
1130 1115
1131#define SMC_GET_TXFIFO() \ 1116#define SMC_GET_TXFIFO(lp) \
1132 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, TXFIFO_REG)) \ 1117 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, TXFIFO_REG(lp))) \
1133 : (SMC_inw(ioaddr, TXFIFO_REG) & 0xFF) ) 1118 : (SMC_inw(ioaddr, TXFIFO_REG(lp)) & 0xFF))
1134 1119
1135#define SMC_GET_RXFIFO() \ 1120#define SMC_GET_RXFIFO(lp) \
1136 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, RXFIFO_REG)) \ 1121 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, RXFIFO_REG(lp))) \
1137 : (SMC_inw(ioaddr, TXFIFO_REG) >> 8) ) 1122 : (SMC_inw(ioaddr, TXFIFO_REG(lp)) >> 8))
1138 1123
1139#define SMC_GET_INT() \ 1124#define SMC_GET_INT(lp) \
1140 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, INT_REG)) \ 1125 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, INT_REG(lp))) \
1141 : (SMC_inw(ioaddr, INT_REG) & 0xFF) ) 1126 : (SMC_inw(ioaddr, INT_REG(lp)) & 0xFF))
1142 1127
1143#define SMC_ACK_INT(x) \ 1128#define SMC_ACK_INT(lp, x) \
1144 do { \ 1129 do { \
1145 if (SMC_CAN_USE_8BIT) \ 1130 if (SMC_8BIT(lp)) \
1146 SMC_outb(x, ioaddr, INT_REG); \ 1131 SMC_outb(x, ioaddr, INT_REG(lp)); \
1147 else { \ 1132 else { \
1148 unsigned long __flags; \ 1133 unsigned long __flags; \
1149 int __mask; \ 1134 int __mask; \
1150 local_irq_save(__flags); \ 1135 local_irq_save(__flags); \
1151 __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ 1136 __mask = SMC_inw(ioaddr, INT_REG(lp)) & ~0xff; \
1152 SMC_outw( __mask | (x), ioaddr, INT_REG ); \ 1137 SMC_outw(__mask | (x), ioaddr, INT_REG(lp)); \
1153 local_irq_restore(__flags); \ 1138 local_irq_restore(__flags); \
1154 } \ 1139 } \
1155 } while (0) 1140 } while (0)
1156 1141
1157#define SMC_GET_INT_MASK() \ 1142#define SMC_GET_INT_MASK(lp) \
1158 ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, IM_REG)) \ 1143 (SMC_8BIT(lp) ? (SMC_inb(ioaddr, IM_REG(lp))) \
1159 : (SMC_inw( ioaddr, INT_REG ) >> 8) ) 1144 : (SMC_inw(ioaddr, INT_REG(lp)) >> 8))
1160 1145
1161#define SMC_SET_INT_MASK(x) \ 1146#define SMC_SET_INT_MASK(lp, x) \
1162 do { \ 1147 do { \
1163 if (SMC_CAN_USE_8BIT) \ 1148 if (SMC_8BIT(lp)) \
1164 SMC_outb(x, ioaddr, IM_REG); \ 1149 SMC_outb(x, ioaddr, IM_REG(lp)); \
1165 else \ 1150 else \
1166 SMC_outw((x) << 8, ioaddr, INT_REG); \ 1151 SMC_outw((x) << 8, ioaddr, INT_REG(lp)); \
1167 } while (0) 1152 } while (0)
1168 1153
1169#define SMC_CURRENT_BANK() SMC_inw(ioaddr, BANK_SELECT) 1154#define SMC_CURRENT_BANK(lp) SMC_inw(ioaddr, BANK_SELECT)
1170 1155
1171#define SMC_SELECT_BANK(x) \ 1156#define SMC_SELECT_BANK(lp, x) \
1172 do { \ 1157 do { \
1173 if (SMC_MUST_ALIGN_WRITE) \ 1158 if (SMC_MUST_ALIGN_WRITE(lp)) \
1174 SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \ 1159 SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \
1175 else \ 1160 else \
1176 SMC_outw(x, ioaddr, BANK_SELECT); \ 1161 SMC_outw(x, ioaddr, BANK_SELECT); \
1177 } while (0) 1162 } while (0)
1178 1163
1179#define SMC_GET_BASE() SMC_inw(ioaddr, BASE_REG) 1164#define SMC_GET_BASE(lp) SMC_inw(ioaddr, BASE_REG(lp))
1180 1165
1181#define SMC_SET_BASE(x) SMC_outw(x, ioaddr, BASE_REG) 1166#define SMC_SET_BASE(lp, x) SMC_outw(x, ioaddr, BASE_REG(lp))
1182 1167
1183#define SMC_GET_CONFIG() SMC_inw(ioaddr, CONFIG_REG) 1168#define SMC_GET_CONFIG(lp) SMC_inw(ioaddr, CONFIG_REG(lp))
1184 1169
1185#define SMC_SET_CONFIG(x) SMC_outw(x, ioaddr, CONFIG_REG) 1170#define SMC_SET_CONFIG(lp, x) SMC_outw(x, ioaddr, CONFIG_REG(lp))
1186 1171
1187#define SMC_GET_COUNTER() SMC_inw(ioaddr, COUNTER_REG) 1172#define SMC_GET_COUNTER(lp) SMC_inw(ioaddr, COUNTER_REG(lp))
1188 1173
1189#define SMC_GET_CTL() SMC_inw(ioaddr, CTL_REG) 1174#define SMC_GET_CTL(lp) SMC_inw(ioaddr, CTL_REG(lp))
1190 1175
1191#define SMC_SET_CTL(x) SMC_outw(x, ioaddr, CTL_REG) 1176#define SMC_SET_CTL(lp, x) SMC_outw(x, ioaddr, CTL_REG(lp))
1192 1177
1193#define SMC_GET_MII() SMC_inw(ioaddr, MII_REG) 1178#define SMC_GET_MII(lp) SMC_inw(ioaddr, MII_REG(lp))
1194 1179
1195#define SMC_SET_MII(x) SMC_outw(x, ioaddr, MII_REG) 1180#define SMC_SET_MII(lp, x) SMC_outw(x, ioaddr, MII_REG(lp))
1196 1181
1197#define SMC_GET_MIR() SMC_inw(ioaddr, MIR_REG) 1182#define SMC_GET_MIR(lp) SMC_inw(ioaddr, MIR_REG(lp))
1198 1183
1199#define SMC_SET_MIR(x) SMC_outw(x, ioaddr, MIR_REG) 1184#define SMC_SET_MIR(lp, x) SMC_outw(x, ioaddr, MIR_REG(lp))
1200 1185
1201#define SMC_GET_MMU_CMD() SMC_inw(ioaddr, MMU_CMD_REG) 1186#define SMC_GET_MMU_CMD(lp) SMC_inw(ioaddr, MMU_CMD_REG(lp))
1202 1187
1203#define SMC_SET_MMU_CMD(x) SMC_outw(x, ioaddr, MMU_CMD_REG) 1188#define SMC_SET_MMU_CMD(lp, x) SMC_outw(x, ioaddr, MMU_CMD_REG(lp))
1204 1189
1205#define SMC_GET_FIFO() SMC_inw(ioaddr, FIFO_REG) 1190#define SMC_GET_FIFO(lp) SMC_inw(ioaddr, FIFO_REG(lp))
1206 1191
1207#define SMC_GET_PTR() SMC_inw(ioaddr, PTR_REG) 1192#define SMC_GET_PTR(lp) SMC_inw(ioaddr, PTR_REG(lp))
1208 1193
1209#define SMC_SET_PTR(x) \ 1194#define SMC_SET_PTR(lp, x) \
1210 do { \ 1195 do { \
1211 if (SMC_MUST_ALIGN_WRITE) \ 1196 if (SMC_MUST_ALIGN_WRITE(lp)) \
1212 SMC_outl((x)<<16, ioaddr, SMC_REG(4, 2)); \ 1197 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 4, 2)); \
1213 else \ 1198 else \
1214 SMC_outw(x, ioaddr, PTR_REG); \ 1199 SMC_outw(x, ioaddr, PTR_REG(lp)); \
1215 } while (0) 1200 } while (0)
1216 1201
1217#define SMC_GET_EPH_STATUS() SMC_inw(ioaddr, EPH_STATUS_REG) 1202#define SMC_GET_EPH_STATUS(lp) SMC_inw(ioaddr, EPH_STATUS_REG(lp))
1218 1203
1219#define SMC_GET_RCR() SMC_inw(ioaddr, RCR_REG) 1204#define SMC_GET_RCR(lp) SMC_inw(ioaddr, RCR_REG(lp))
1220 1205
1221#define SMC_SET_RCR(x) SMC_outw(x, ioaddr, RCR_REG) 1206#define SMC_SET_RCR(lp, x) SMC_outw(x, ioaddr, RCR_REG(lp))
1222 1207
1223#define SMC_GET_REV() SMC_inw(ioaddr, REV_REG) 1208#define SMC_GET_REV(lp) SMC_inw(ioaddr, REV_REG(lp))
1224 1209
1225#define SMC_GET_RPC() SMC_inw(ioaddr, RPC_REG) 1210#define SMC_GET_RPC(lp) SMC_inw(ioaddr, RPC_REG(lp))
1226 1211
1227#define SMC_SET_RPC(x) \ 1212#define SMC_SET_RPC(lp, x) \
1228 do { \ 1213 do { \
1229 if (SMC_MUST_ALIGN_WRITE) \ 1214 if (SMC_MUST_ALIGN_WRITE(lp)) \
1230 SMC_outl((x)<<16, ioaddr, SMC_REG(8, 0)); \ 1215 SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 0)); \
1231 else \ 1216 else \
1232 SMC_outw(x, ioaddr, RPC_REG); \ 1217 SMC_outw(x, ioaddr, RPC_REG(lp)); \
1233 } while (0) 1218 } while (0)
1234 1219
1235#define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG) 1220#define SMC_GET_TCR(lp) SMC_inw(ioaddr, TCR_REG(lp))
1236 1221
1237#define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG) 1222#define SMC_SET_TCR(lp, x) SMC_outw(x, ioaddr, TCR_REG(lp))
1238 1223
1239#ifndef SMC_GET_MAC_ADDR 1224#ifndef SMC_GET_MAC_ADDR
1240#define SMC_GET_MAC_ADDR(addr) \ 1225#define SMC_GET_MAC_ADDR(lp, addr) \
1241 do { \ 1226 do { \
1242 unsigned int __v; \ 1227 unsigned int __v; \
1243 __v = SMC_inw( ioaddr, ADDR0_REG ); \ 1228 __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \
1244 addr[0] = __v; addr[1] = __v >> 8; \ 1229 addr[0] = __v; addr[1] = __v >> 8; \
1245 __v = SMC_inw( ioaddr, ADDR1_REG ); \ 1230 __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \
1246 addr[2] = __v; addr[3] = __v >> 8; \ 1231 addr[2] = __v; addr[3] = __v >> 8; \
1247 __v = SMC_inw( ioaddr, ADDR2_REG ); \ 1232 __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \
1248 addr[4] = __v; addr[5] = __v >> 8; \ 1233 addr[4] = __v; addr[5] = __v >> 8; \
1249 } while (0) 1234 } while (0)
1250#endif 1235#endif
1251 1236
1252#define SMC_SET_MAC_ADDR(addr) \ 1237#define SMC_SET_MAC_ADDR(lp, addr) \
1253 do { \ 1238 do { \
1254 SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG ); \ 1239 SMC_outw(addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG(lp)); \
1255 SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG ); \ 1240 SMC_outw(addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG(lp)); \
1256 SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG ); \ 1241 SMC_outw(addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG(lp)); \
1257 } while (0) 1242 } while (0)
1258 1243
1259#define SMC_SET_MCAST(x) \ 1244#define SMC_SET_MCAST(lp, x) \
1260 do { \ 1245 do { \
1261 const unsigned char *mt = (x); \ 1246 const unsigned char *mt = (x); \
1262 SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 ); \ 1247 SMC_outw(mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1(lp)); \
1263 SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 ); \ 1248 SMC_outw(mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2(lp)); \
1264 SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 ); \ 1249 SMC_outw(mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3(lp)); \
1265 SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ 1250 SMC_outw(mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4(lp)); \
1266 } while (0) 1251 } while (0)
1267 1252
1268#define SMC_PUT_PKT_HDR(status, length) \ 1253#define SMC_PUT_PKT_HDR(lp, status, length) \
1269 do { \ 1254 do { \
1270 if (SMC_CAN_USE_32BIT) \ 1255 if (SMC_32BIT(lp)) \
1271 SMC_outl((status) | (length)<<16, ioaddr, DATA_REG); \ 1256 SMC_outl((status) | (length)<<16, ioaddr, \
1257 DATA_REG(lp)); \
1272 else { \ 1258 else { \
1273 SMC_outw(status, ioaddr, DATA_REG); \ 1259 SMC_outw(status, ioaddr, DATA_REG(lp)); \
1274 SMC_outw(length, ioaddr, DATA_REG); \ 1260 SMC_outw(length, ioaddr, DATA_REG(lp)); \
1275 } \ 1261 } \
1276 } while (0) 1262 } while (0)
1277 1263
1278#define SMC_GET_PKT_HDR(status, length) \ 1264#define SMC_GET_PKT_HDR(lp, status, length) \
1279 do { \ 1265 do { \
1280 if (SMC_CAN_USE_32BIT) { \ 1266 if (SMC_32BIT(lp)) { \
1281 unsigned int __val = SMC_inl(ioaddr, DATA_REG); \ 1267 unsigned int __val = SMC_inl(ioaddr, DATA_REG(lp)); \
1282 (status) = __val & 0xffff; \ 1268 (status) = __val & 0xffff; \
1283 (length) = __val >> 16; \ 1269 (length) = __val >> 16; \
1284 } else { \ 1270 } else { \
1285 (status) = SMC_inw(ioaddr, DATA_REG); \ 1271 (status) = SMC_inw(ioaddr, DATA_REG(lp)); \
1286 (length) = SMC_inw(ioaddr, DATA_REG); \ 1272 (length) = SMC_inw(ioaddr, DATA_REG(lp)); \
1287 } \ 1273 } \
1288 } while (0) 1274 } while (0)
1289 1275
1290#define SMC_PUSH_DATA(p, l) \ 1276#define SMC_PUSH_DATA(lp, p, l) \
1291 do { \ 1277 do { \
1292 if (SMC_CAN_USE_32BIT) { \ 1278 if (SMC_32BIT(lp)) { \
1293 void *__ptr = (p); \ 1279 void *__ptr = (p); \
1294 int __len = (l); \ 1280 int __len = (l); \
1295 void __iomem *__ioaddr = ioaddr; \ 1281 void __iomem *__ioaddr = ioaddr; \
1296 if (__len >= 2 && (unsigned long)__ptr & 2) { \ 1282 if (__len >= 2 && (unsigned long)__ptr & 2) { \
1297 __len -= 2; \ 1283 __len -= 2; \
1298 SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \ 1284 SMC_outw(*(u16 *)__ptr, ioaddr, \
1285 DATA_REG(lp)); \
1299 __ptr += 2; \ 1286 __ptr += 2; \
1300 } \ 1287 } \
1301 if (SMC_CAN_USE_DATACS && lp->datacs) \ 1288 if (SMC_CAN_USE_DATACS && lp->datacs) \
1302 __ioaddr = lp->datacs; \ 1289 __ioaddr = lp->datacs; \
1303 SMC_outsl(__ioaddr, DATA_REG, __ptr, __len>>2); \ 1290 SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
1304 if (__len & 2) { \ 1291 if (__len & 2) { \
1305 __ptr += (__len & ~3); \ 1292 __ptr += (__len & ~3); \
1306 SMC_outw(*((u16 *)__ptr), ioaddr, DATA_REG); \ 1293 SMC_outw(*((u16 *)__ptr), ioaddr, \
1294 DATA_REG(lp)); \
1307 } \ 1295 } \
1308 } else if (SMC_CAN_USE_16BIT) \ 1296 } else if (SMC_16BIT(lp)) \
1309 SMC_outsw(ioaddr, DATA_REG, p, (l) >> 1); \ 1297 SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1); \
1310 else if (SMC_CAN_USE_8BIT) \ 1298 else if (SMC_8BIT(lp)) \
1311 SMC_outsb(ioaddr, DATA_REG, p, l); \ 1299 SMC_outsb(ioaddr, DATA_REG(lp), p, l); \
1312 } while (0) 1300 } while (0)
1313 1301
1314#define SMC_PULL_DATA(p, l) \ 1302#define SMC_PULL_DATA(lp, p, l) \
1315 do { \ 1303 do { \
1316 if (SMC_CAN_USE_32BIT) { \ 1304 if (SMC_32BIT(lp)) { \
1317 void *__ptr = (p); \ 1305 void *__ptr = (p); \
1318 int __len = (l); \ 1306 int __len = (l); \
1319 void __iomem *__ioaddr = ioaddr; \ 1307 void __iomem *__ioaddr = ioaddr; \
@@ -1333,16 +1321,17 @@ static const char * chip_ids[ 16 ] = {
1333 */ \ 1321 */ \
1334 __ptr -= 2; \ 1322 __ptr -= 2; \
1335 __len += 2; \ 1323 __len += 2; \
1336 SMC_SET_PTR(2|PTR_READ|PTR_RCV|PTR_AUTOINC); \ 1324 SMC_SET_PTR(lp, \
1325 2|PTR_READ|PTR_RCV|PTR_AUTOINC); \
1337 } \ 1326 } \
1338 if (SMC_CAN_USE_DATACS && lp->datacs) \ 1327 if (SMC_CAN_USE_DATACS && lp->datacs) \
1339 __ioaddr = lp->datacs; \ 1328 __ioaddr = lp->datacs; \
1340 __len += 2; \ 1329 __len += 2; \
1341 SMC_insl(__ioaddr, DATA_REG, __ptr, __len>>2); \ 1330 SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
1342 } else if (SMC_CAN_USE_16BIT) \ 1331 } else if (SMC_16BIT(lp)) \
1343 SMC_insw(ioaddr, DATA_REG, p, (l) >> 1); \ 1332 SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1); \
1344 else if (SMC_CAN_USE_8BIT) \ 1333 else if (SMC_8BIT(lp)) \
1345 SMC_insb(ioaddr, DATA_REG, p, l); \ 1334 SMC_insb(ioaddr, DATA_REG(lp), p, l); \
1346 } while (0) 1335 } while (0)
1347 1336
1348#endif /* _SMC91X_H_ */ 1337#endif /* _SMC91X_H_ */
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index 20ac1503021e..d913405bc393 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -141,7 +141,7 @@ config ULI526X
141 be called uli526x. 141 be called uli526x.
142 142
143config PCMCIA_XIRCOM 143config PCMCIA_XIRCOM
144 tristate "Xircom CardBus support (new driver)" 144 tristate "Xircom CardBus support"
145 depends on CARDBUS 145 depends on CARDBUS
146 ---help--- 146 ---help---
147 This driver is for the Digital "Tulip" Ethernet CardBus adapters. 147 This driver is for the Digital "Tulip" Ethernet CardBus adapters.
@@ -152,17 +152,4 @@ config PCMCIA_XIRCOM
152 To compile this driver as a module, choose M here. The module will 152 To compile this driver as a module, choose M here. The module will
153 be called xircom_cb. If unsure, say N. 153 be called xircom_cb. If unsure, say N.
154 154
155config PCMCIA_XIRTULIP
156 tristate "Xircom Tulip-like CardBus support (old driver)"
157 depends on CARDBUS && BROKEN_ON_SMP
158 select CRC32
159 ---help---
160 This driver is for the Digital "Tulip" Ethernet CardBus adapters.
161 It should work with most DEC 21*4*-based chips/ethercards, as well
162 as with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and
163 ASIX.
164
165 To compile this driver as a module, choose M here. The module will
166 be called xircom_tulip_cb. If unsure, say N.
167
168endif # NET_TULIP 155endif # NET_TULIP
diff --git a/drivers/net/tulip/Makefile b/drivers/net/tulip/Makefile
index 451090d6fcca..200cbf7c815c 100644
--- a/drivers/net/tulip/Makefile
+++ b/drivers/net/tulip/Makefile
@@ -2,7 +2,6 @@
2# Makefile for the Linux "Tulip" family network device drivers. 2# Makefile for the Linux "Tulip" family network device drivers.
3# 3#
4 4
5obj-$(CONFIG_PCMCIA_XIRTULIP) += xircom_tulip_cb.o
6obj-$(CONFIG_PCMCIA_XIRCOM) += xircom_cb.o 5obj-$(CONFIG_PCMCIA_XIRCOM) += xircom_cb.o
7obj-$(CONFIG_DM9102) += dmfe.o 6obj-$(CONFIG_DM9102) += dmfe.o
8obj-$(CONFIG_WINBOND_840) += winbond-840.o 7obj-$(CONFIG_WINBOND_840) += winbond-840.o
diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c
deleted file mode 100644
index c3f8e303c6c7..000000000000
--- a/drivers/net/tulip/xircom_tulip_cb.c
+++ /dev/null
@@ -1,1726 +0,0 @@
1/* xircom_tulip_cb.c: A Xircom CBE-100 ethernet driver for Linux. */
2/*
3 Written/copyright 1994-1999 by Donald Becker.
4
5 This software may be used and distributed according to the terms
6 of the GNU General Public License, incorporated herein by reference.
7
8 The author may be reached as becker@scyld.com, or C/O
9 Scyld Computing Corporation
10 410 Severn Ave., Suite 210
11 Annapolis MD 21403
12
13*/
14
15#define DRV_NAME "xircom_tulip_cb"
16#define DRV_VERSION "0.92"
17#define DRV_RELDATE "June 27, 2006"
18
19/* A few user-configurable values. */
20
21#define xircom_debug debug
22#ifdef XIRCOM_DEBUG
23static int xircom_debug = XIRCOM_DEBUG;
24#else
25static int xircom_debug = 1;
26#endif
27
28/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
29static int max_interrupt_work = 25;
30
31#define MAX_UNITS 4
32/* Used to pass the full-duplex flag, etc. */
33static int full_duplex[MAX_UNITS];
34static int options[MAX_UNITS];
35static int mtu[MAX_UNITS]; /* Jumbo MTU for interfaces. */
36
37/* Keep the ring sizes a power of two for efficiency.
38 Making the Tx ring too large decreases the effectiveness of channel
39 bonding and packet priority.
40 There are no ill effects from too-large receive rings. */
41#define TX_RING_SIZE 16
42#define RX_RING_SIZE 32
43
44/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
45#ifdef __alpha__
46static int rx_copybreak = 1518;
47#else
48static int rx_copybreak = 100;
49#endif
50
51/*
52 Set the bus performance register.
53 Typical: Set 16 longword cache alignment, no burst limit.
54 Cache alignment bits 15:14 Burst length 13:8
55 0000 No alignment 0x00000000 unlimited 0800 8 longwords
56 4000 8 longwords 0100 1 longword 1000 16 longwords
57 8000 16 longwords 0200 2 longwords 2000 32 longwords
58 C000 32 longwords 0400 4 longwords
59 Warning: many older 486 systems are broken and require setting 0x00A04800
60 8 longword cache alignment, 8 longword burst.
61 ToDo: Non-Intel setting could be better.
62*/
63
64#if defined(__alpha__) || defined(__ia64__) || defined(__x86_64__)
65static int csr0 = 0x01A00000 | 0xE000;
66#elif defined(__powerpc__)
67static int csr0 = 0x01B00000 | 0x8000;
68#elif defined(CONFIG_SPARC)
69static int csr0 = 0x01B00080 | 0x8000;
70#elif defined(__i386__)
71static int csr0 = 0x01A00000 | 0x8000;
72#else
73#warning Processor architecture undefined!
74static int csr0 = 0x00A00000 | 0x4800;
75#endif
76
77/* Operational parameters that usually are not changed. */
78/* Time in jiffies before concluding the transmitter is hung. */
79#define TX_TIMEOUT (4 * HZ)
80#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
81#define PKT_SETUP_SZ 192 /* Size of the setup frame */
82
83/* PCI registers */
84#define PCI_POWERMGMT 0x40
85
86#include <linux/module.h>
87#include <linux/moduleparam.h>
88#include <linux/kernel.h>
89#include <linux/pci.h>
90#include <linux/netdevice.h>
91#include <linux/etherdevice.h>
92#include <linux/delay.h>
93#include <linux/init.h>
94#include <linux/mii.h>
95#include <linux/ethtool.h>
96#include <linux/crc32.h>
97
98#include <asm/io.h>
99#include <asm/processor.h> /* Processor type for cache alignment. */
100#include <asm/uaccess.h>
101
102
103/* These identify the driver base version and may not be removed. */
104static char version[] __devinitdata =
105KERN_INFO DRV_NAME ".c derived from tulip.c:v0.91 4/14/99 becker@scyld.com\n"
106KERN_INFO " unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE "\n";
107
108MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
109MODULE_DESCRIPTION("Xircom CBE-100 ethernet driver");
110MODULE_LICENSE("GPL v2");
111MODULE_VERSION(DRV_VERSION);
112
113module_param(debug, int, 0);
114module_param(max_interrupt_work, int, 0);
115module_param(rx_copybreak, int, 0);
116module_param(csr0, int, 0);
117
118module_param_array(options, int, NULL, 0);
119module_param_array(full_duplex, int, NULL, 0);
120
121#define RUN_AT(x) (jiffies + (x))
122
123/*
124 Theory of Operation
125
126I. Board Compatibility
127
128This device driver was forked from the driver for the DECchip "Tulip",
129Digital's single-chip ethernet controllers for PCI. It supports Xircom's
130almost-Tulip-compatible CBE-100 CardBus adapters.
131
132II. Board-specific settings
133
134PCI bus devices are configured by the system at boot time, so no jumpers
135need to be set on the board. The system BIOS preferably should assign the
136PCI INTA signal to an otherwise unused system IRQ line.
137
138III. Driver operation
139
140IIIa. Ring buffers
141
142The Xircom can use either ring buffers or lists of Tx and Rx descriptors.
143This driver uses statically allocated rings of Rx and Tx descriptors, set at
144compile time by RX/TX_RING_SIZE. This version of the driver allocates skbuffs
145for the Rx ring buffers at open() time and passes the skb->data field to the
146Xircom as receive data buffers. When an incoming frame is less than
147RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is
148copied to the new skbuff. When the incoming frame is larger, the skbuff is
149passed directly up the protocol stack and replaced by a newly allocated
150skbuff.
151
152The RX_COPYBREAK value is chosen to trade-off the memory wasted by
153using a full-sized skbuff for small frames vs. the copying costs of larger
154frames. For small frames the copying cost is negligible (esp. considering
155that we are pre-loading the cache with immediately useful header
156information). For large frames the copying cost is non-trivial, and the
157larger copy might flush the cache of useful data. A subtle aspect of this
158choice is that the Xircom only receives into longword aligned buffers, thus
159the IP header at offset 14 isn't longword aligned for further processing.
160Copied frames are put into the new skbuff at an offset of "+2", thus copying
161has the beneficial effect of aligning the IP header and preloading the
162cache.
163
164IIIC. Synchronization
165The driver runs as two independent, single-threaded flows of control. One
166is the send-packet routine, which enforces single-threaded use by the
167dev->tbusy flag. The other thread is the interrupt handler, which is single
168threaded by the hardware and other software.
169
170The send packet thread has partial control over the Tx ring and 'dev->tbusy'
171flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
172queue slot is empty, it clears the tbusy flag when finished otherwise it sets
173the 'tp->tx_full' flag.
174
175The interrupt handler has exclusive control over the Rx ring and records stats
176from the Tx ring. (The Tx-done interrupt can't be selectively turned off, so
177we can't avoid the interrupt overhead by having the Tx routine reap the Tx
178stats.) After reaping the stats, it marks the queue entry as empty by setting
179the 'base' to zero. Iff the 'tp->tx_full' flag is set, it clears both the
180tx_full and tbusy flags.
181
182IV. Notes
183
184IVb. References
185
186http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
187http://www.digital.com (search for current 21*4* datasheets and "21X4 SROM")
188http://www.national.com/pf/DP/DP83840A.html
189
190IVc. Errata
191
192*/
193
194/* A full-duplex map for media types. */
195enum MediaIs {
196 MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8,
197 MediaIs100=16};
198static const char media_cap[] =
199{0,0,0,16, 3,19,16,24, 27,4,7,5, 0,20,23,20 };
200
201/* Offsets to the Command and Status Registers, "CSRs". All accesses
202 must be longword instructions and quadword aligned. */
203enum xircom_offsets {
204 CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
205 CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
206 CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x04, };
207
208/* The bits in the CSR5 status registers, mostly interrupt sources. */
209enum status_bits {
210 LinkChange=0x08000000,
211 NormalIntr=0x10000, NormalIntrMask=0x00014045,
212 AbnormalIntr=0x8000, AbnormalIntrMask=0x0a00a5a2,
213 ReservedIntrMask=0xe0001a18,
214 EarlyRxIntr=0x4000, BusErrorIntr=0x2000,
215 EarlyTxIntr=0x400, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
216 TxFIFOUnderflow=0x20, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
217};
218
219enum csr0_control_bits {
220 EnableMWI=0x01000000, EnableMRL=0x00800000,
221 EnableMRM=0x00200000, EqualBusPrio=0x02,
222 SoftwareReset=0x01,
223};
224
225enum csr6_control_bits {
226 ReceiveAllBit=0x40000000, AllMultiBit=0x80, PromiscBit=0x40,
227 HashFilterBit=0x01, FullDuplexBit=0x0200,
228 TxThresh10=0x400000, TxStoreForw=0x200000,
229 TxThreshMask=0xc000, TxThreshShift=14,
230 EnableTx=0x2000, EnableRx=0x02,
231 ReservedZeroMask=0x8d930134, ReservedOneMask=0x320c0000,
232 EnableTxRx=(EnableTx | EnableRx),
233};
234
235
236enum tbl_flag {
237 HAS_MII=1, HAS_ACPI=2,
238};
239static struct xircom_chip_table {
240 char *chip_name;
241 int valid_intrs; /* CSR7 interrupt enable settings */
242 int flags;
243} xircom_tbl[] = {
244 { "Xircom Cardbus Adapter",
245 LinkChange | NormalIntr | AbnormalIntr | BusErrorIntr |
246 RxDied | RxNoBuf | RxIntr | TxFIFOUnderflow | TxNoBuf | TxDied | TxIntr,
247 HAS_MII | HAS_ACPI, },
248 { NULL, },
249};
250/* This matches the table above. */
251enum chips {
252 X3201_3,
253};
254
255
256/* The Xircom Rx and Tx buffer descriptors. */
257struct xircom_rx_desc {
258 s32 status;
259 s32 length;
260 u32 buffer1, buffer2;
261};
262
263struct xircom_tx_desc {
264 s32 status;
265 s32 length;
266 u32 buffer1, buffer2; /* We use only buffer 1. */
267};
268
269enum tx_desc0_status_bits {
270 Tx0DescOwned=0x80000000, Tx0DescError=0x8000, Tx0NoCarrier=0x0800,
271 Tx0LateColl=0x0200, Tx0ManyColl=0x0100, Tx0Underflow=0x02,
272};
273enum tx_desc1_status_bits {
274 Tx1ComplIntr=0x80000000, Tx1LastSeg=0x40000000, Tx1FirstSeg=0x20000000,
275 Tx1SetupPkt=0x08000000, Tx1DisableCRC=0x04000000, Tx1RingWrap=0x02000000,
276 Tx1ChainDesc=0x01000000, Tx1NoPad=0x800000, Tx1HashSetup=0x400000,
277 Tx1WholePkt=(Tx1FirstSeg | Tx1LastSeg),
278};
279enum rx_desc0_status_bits {
280 Rx0DescOwned=0x80000000, Rx0DescError=0x8000, Rx0NoSpace=0x4000,
281 Rx0Runt=0x0800, Rx0McastPkt=0x0400, Rx0FirstSeg=0x0200, Rx0LastSeg=0x0100,
282 Rx0HugeFrame=0x80, Rx0CRCError=0x02,
283 Rx0WholePkt=(Rx0FirstSeg | Rx0LastSeg),
284};
285enum rx_desc1_status_bits {
286 Rx1RingWrap=0x02000000, Rx1ChainDesc=0x01000000,
287};
288
289struct xircom_private {
290 struct xircom_rx_desc rx_ring[RX_RING_SIZE];
291 struct xircom_tx_desc tx_ring[TX_RING_SIZE];
292 /* The saved address of a sent-in-place packet/buffer, for skfree(). */
293 struct sk_buff* tx_skbuff[TX_RING_SIZE];
294
295 /* The X3201-3 requires 4-byte aligned tx bufs */
296 struct sk_buff* tx_aligned_skbuff[TX_RING_SIZE];
297
298 /* The addresses of receive-in-place skbuffs. */
299 struct sk_buff* rx_skbuff[RX_RING_SIZE];
300 u16 setup_frame[PKT_SETUP_SZ / sizeof(u16)]; /* Pseudo-Tx frame to init address table. */
301 int chip_id;
302 struct net_device_stats stats;
303 unsigned int cur_rx, cur_tx; /* The next free ring entry */
304 unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
305 unsigned int tx_full:1; /* The Tx queue is full. */
306 unsigned int speed100:1;
307 unsigned int full_duplex:1; /* Full-duplex operation requested. */
308 unsigned int autoneg:1;
309 unsigned int default_port:4; /* Last dev->if_port value. */
310 unsigned int open:1;
311 unsigned int csr0; /* CSR0 setting. */
312 unsigned int csr6; /* Current CSR6 control settings. */
313 u16 to_advertise; /* NWay capabilities advertised. */
314 u16 advertising[4];
315 signed char phys[4], mii_cnt; /* MII device addresses. */
316 int saved_if_port;
317 struct pci_dev *pdev;
318 spinlock_t lock;
319};
320
321static int mdio_read(struct net_device *dev, int phy_id, int location);
322static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
323static void xircom_up(struct net_device *dev);
324static void xircom_down(struct net_device *dev);
325static int xircom_open(struct net_device *dev);
326static void xircom_tx_timeout(struct net_device *dev);
327static void xircom_init_ring(struct net_device *dev);
328static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);
329static int xircom_rx(struct net_device *dev);
330static void xircom_media_change(struct net_device *dev);
331static irqreturn_t xircom_interrupt(int irq, void *dev_instance);
332static int xircom_close(struct net_device *dev);
333static struct net_device_stats *xircom_get_stats(struct net_device *dev);
334static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
335static void set_rx_mode(struct net_device *dev);
336static void check_duplex(struct net_device *dev);
337static const struct ethtool_ops ops;
338
339
340/* The Xircom cards are picky about when certain bits in CSR6 can be
341 manipulated. Keith Owens <kaos@ocs.com.au>. */
342static void outl_CSR6(u32 newcsr6, long ioaddr)
343{
344 const int strict_bits =
345 TxThresh10 | TxStoreForw | TxThreshMask | EnableTxRx | FullDuplexBit;
346 int csr5, csr5_22_20, csr5_19_17, currcsr6, attempts = 200;
347 unsigned long flags;
348 save_flags(flags);
349 cli();
350 /* mask out the reserved bits that always read 0 on the Xircom cards */
351 newcsr6 &= ~ReservedZeroMask;
352 /* or in the reserved bits that always read 1 */
353 newcsr6 |= ReservedOneMask;
354 currcsr6 = inl(ioaddr + CSR6);
355 if (((newcsr6 & strict_bits) == (currcsr6 & strict_bits)) ||
356 ((currcsr6 & ~EnableTxRx) == 0)) {
357 outl(newcsr6, ioaddr + CSR6); /* safe */
358 restore_flags(flags);
359 return;
360 }
361 /* make sure the transmitter and receiver are stopped first */
362 currcsr6 &= ~EnableTxRx;
363 while (1) {
364 csr5 = inl(ioaddr + CSR5);
365 if (csr5 == 0xffffffff)
366 break; /* cannot read csr5, card removed? */
367 csr5_22_20 = csr5 & 0x700000;
368 csr5_19_17 = csr5 & 0x0e0000;
369 if ((csr5_22_20 == 0 || csr5_22_20 == 0x600000) &&
370 (csr5_19_17 == 0 || csr5_19_17 == 0x80000 || csr5_19_17 == 0xc0000))
371 break; /* both are stopped or suspended */
372 if (!--attempts) {
373 printk(KERN_INFO DRV_NAME ": outl_CSR6 too many attempts,"
374 "csr5=0x%08x\n", csr5);
375 outl(newcsr6, ioaddr + CSR6); /* unsafe but do it anyway */
376 restore_flags(flags);
377 return;
378 }
379 outl(currcsr6, ioaddr + CSR6);
380 udelay(1);
381 }
382 /* now it is safe to change csr6 */
383 outl(newcsr6, ioaddr + CSR6);
384 restore_flags(flags);
385}
386
387
388static void __devinit read_mac_address(struct net_device *dev)
389{
390 long ioaddr = dev->base_addr;
391 int i, j;
392 unsigned char tuple, link, data_id, data_count;
393
394 /* Xircom has its address stored in the CIS;
395 * we access it through the boot rom interface for now
396 * this might not work, as the CIS is not parsed but I
397 * (danilo) use the offset I found on my card's CIS !!!
398 *
399 * Doug Ledford: I changed this routine around so that it
400 * walks the CIS memory space, parsing the config items, and
401 * finds the proper lan_node_id tuple and uses the data
402 * stored there.
403 */
404 outl(1 << 12, ioaddr + CSR9); /* enable boot rom access */
405 for (i = 0x100; i < 0x1f7; i += link+2) {
406 outl(i, ioaddr + CSR10);
407 tuple = inl(ioaddr + CSR9) & 0xff;
408 outl(i + 1, ioaddr + CSR10);
409 link = inl(ioaddr + CSR9) & 0xff;
410 outl(i + 2, ioaddr + CSR10);
411 data_id = inl(ioaddr + CSR9) & 0xff;
412 outl(i + 3, ioaddr + CSR10);
413 data_count = inl(ioaddr + CSR9) & 0xff;
414 if ( (tuple == 0x22) &&
415 (data_id == 0x04) && (data_count == 0x06) ) {
416 /*
417 * This is it. We have the data we want.
418 */
419 for (j = 0; j < 6; j++) {
420 outl(i + j + 4, ioaddr + CSR10);
421 dev->dev_addr[j] = inl(ioaddr + CSR9) & 0xff;
422 }
423 break;
424 } else if (link == 0) {
425 break;
426 }
427 }
428}
429
430
431/*
432 * locate the MII interfaces and initialize them.
433 * we disable full-duplex modes here,
434 * because we don't know how to handle them.
435 */
436static void find_mii_transceivers(struct net_device *dev)
437{
438 struct xircom_private *tp = netdev_priv(dev);
439 int phy, phy_idx;
440
441 if (media_cap[tp->default_port] & MediaIsMII) {
442 u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
443 tp->to_advertise = media2advert[tp->default_port - 9];
444 } else
445 tp->to_advertise =
446 /*ADVERTISE_100BASE4 | ADVERTISE_100FULL |*/ ADVERTISE_100HALF |
447 /*ADVERTISE_10FULL |*/ ADVERTISE_10HALF | ADVERTISE_CSMA;
448
449 /* Find the connected MII xcvrs.
450 Doing this in open() would allow detecting external xcvrs later,
451 but takes much time. */
452 for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) {
453 int mii_status = mdio_read(dev, phy, MII_BMSR);
454 if ((mii_status & (BMSR_100BASE4 | BMSR_100HALF | BMSR_10HALF)) == BMSR_100BASE4 ||
455 ((mii_status & BMSR_100BASE4) == 0 &&
456 (mii_status & (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL | BMSR_10HALF)) != 0)) {
457 int mii_reg0 = mdio_read(dev, phy, MII_BMCR);
458 int mii_advert = mdio_read(dev, phy, MII_ADVERTISE);
459 int reg4 = ((mii_status >> 6) & tp->to_advertise) | ADVERTISE_CSMA;
460 tp->phys[phy_idx] = phy;
461 tp->advertising[phy_idx++] = reg4;
462 printk(KERN_INFO "%s: MII transceiver #%d "
463 "config %4.4x status %4.4x advertising %4.4x.\n",
464 dev->name, phy, mii_reg0, mii_status, mii_advert);
465 }
466 }
467 tp->mii_cnt = phy_idx;
468 if (phy_idx == 0) {
469 printk(KERN_INFO "%s: ***WARNING***: No MII transceiver found!\n",
470 dev->name);
471 tp->phys[0] = 0;
472 }
473}
474
475
476/*
477 * To quote Arjan van de Ven:
478 * transceiver_voodoo() enables the external UTP plug thingy.
479 * it's called voodoo as I stole this code and cannot cross-reference
480 * it with the specification.
481 * Actually it seems to go like this:
482 * - GPIO2 enables the MII itself so we can talk to it. The MII gets reset
483 * so any prior MII settings are lost.
484 * - GPIO0 enables the TP port so the MII can talk to the network.
485 * - a software reset will reset both GPIO pins.
486 * I also moved the software reset here, because doing it in xircom_up()
487 * required enabling the GPIO pins each time, which reset the MII each time.
488 * Thus we couldn't control the MII -- which sucks because we don't know
489 * how to handle full-duplex modes so we *must* disable them.
490 */
491static void transceiver_voodoo(struct net_device *dev)
492{
493 struct xircom_private *tp = netdev_priv(dev);
494 long ioaddr = dev->base_addr;
495
496 /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
497 outl(SoftwareReset, ioaddr + CSR0);
498 udelay(2);
499
500 /* Deassert reset. */
501 outl(tp->csr0, ioaddr + CSR0);
502
503 /* Reset the xcvr interface and turn on heartbeat. */
504 outl(0x0008, ioaddr + CSR15);
505 udelay(5); /* The delays are Xircom-recommended to give the
506 * chipset time to reset the actual hardware
507 * on the PCMCIA card
508 */
509 outl(0xa8050000, ioaddr + CSR15);
510 udelay(5);
511 outl(0xa00f0000, ioaddr + CSR15);
512 udelay(5);
513
514 outl_CSR6(0, ioaddr);
515 //outl_CSR6(FullDuplexBit, ioaddr);
516}
517
518
519static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
520{
521 struct net_device *dev;
522 struct xircom_private *tp;
523 static int board_idx = -1;
524 int chip_idx = id->driver_data;
525 long ioaddr;
526 int i;
527
528/* when built into the kernel, we only print version if device is found */
529#ifndef MODULE
530 static int printed_version;
531 if (!printed_version++)
532 printk(version);
533#endif
534
535 //printk(KERN_INFO "xircom_init_one(%s)\n", pci_name(pdev));
536
537 board_idx++;
538
539 if (pci_enable_device(pdev))
540 return -ENODEV;
541
542 pci_set_master(pdev);
543
544 ioaddr = pci_resource_start(pdev, 0);
545 dev = alloc_etherdev(sizeof(*tp));
546 if (!dev) {
547 printk (KERN_ERR DRV_NAME "%d: cannot alloc etherdev, aborting\n", board_idx);
548 return -ENOMEM;
549 }
550 SET_NETDEV_DEV(dev, &pdev->dev);
551
552 dev->base_addr = ioaddr;
553 dev->irq = pdev->irq;
554
555 if (pci_request_regions(pdev, dev->name)) {
556 printk (KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", board_idx);
557 goto err_out_free_netdev;
558 }
559
560 /* Bring the chip out of sleep mode.
561 Caution: Snooze mode does not work with some boards! */
562 if (xircom_tbl[chip_idx].flags & HAS_ACPI)
563 pci_write_config_dword(pdev, PCI_POWERMGMT, 0);
564
565 /* Stop the chip's Tx and Rx processes. */
566 outl_CSR6(inl(ioaddr + CSR6) & ~EnableTxRx, ioaddr);
567 /* Clear the missed-packet counter. */
568 (volatile int)inl(ioaddr + CSR8);
569
570 tp = netdev_priv(dev);
571
572 spin_lock_init(&tp->lock);
573 tp->pdev = pdev;
574 tp->chip_id = chip_idx;
575 /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles. */
576 /* XXX: is this necessary for Xircom? */
577 tp->csr0 = csr0 & ~EnableMWI;
578
579 pci_set_drvdata(pdev, dev);
580
581 /* The lower four bits are the media type. */
582 if (board_idx >= 0 && board_idx < MAX_UNITS) {
583 tp->default_port = options[board_idx] & 15;
584 if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0)
585 tp->full_duplex = 1;
586 if (mtu[board_idx] > 0)
587 dev->mtu = mtu[board_idx];
588 }
589 if (dev->mem_start)
590 tp->default_port = dev->mem_start;
591 if (tp->default_port) {
592 if (media_cap[tp->default_port] & MediaAlwaysFD)
593 tp->full_duplex = 1;
594 }
595 if (tp->full_duplex)
596 tp->autoneg = 0;
597 else
598 tp->autoneg = 1;
599 tp->speed100 = 1;
600
601 /* The Xircom-specific entries in the device structure. */
602 dev->open = &xircom_open;
603 dev->hard_start_xmit = &xircom_start_xmit;
604 dev->stop = &xircom_close;
605 dev->get_stats = &xircom_get_stats;
606 dev->do_ioctl = &xircom_ioctl;
607#ifdef HAVE_MULTICAST
608 dev->set_multicast_list = &set_rx_mode;
609#endif
610 dev->tx_timeout = xircom_tx_timeout;
611 dev->watchdog_timeo = TX_TIMEOUT;
612 SET_ETHTOOL_OPS(dev, &ops);
613
614 transceiver_voodoo(dev);
615
616 read_mac_address(dev);
617
618 if (register_netdev(dev))
619 goto err_out_cleardev;
620
621 printk(KERN_INFO "%s: %s rev %d at %#3lx,",
622 dev->name, xircom_tbl[chip_idx].chip_name, pdev->revision, ioaddr);
623 for (i = 0; i < 6; i++)
624 printk("%c%2.2X", i ? ':' : ' ', dev->dev_addr[i]);
625 printk(", IRQ %d.\n", dev->irq);
626
627 if (xircom_tbl[chip_idx].flags & HAS_MII) {
628 find_mii_transceivers(dev);
629 check_duplex(dev);
630 }
631
632 return 0;
633
634err_out_cleardev:
635 pci_set_drvdata(pdev, NULL);
636 pci_release_regions(pdev);
637err_out_free_netdev:
638 free_netdev(dev);
639 return -ENODEV;
640}
641
642
643/* MII transceiver control section.
644 Read and write the MII registers using software-generated serial
645 MDIO protocol. See the MII specifications or DP83840A data sheet
646 for details. */
647
648/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
649 met by back-to-back PCI I/O cycles, but we insert a delay to avoid
650 "overclocking" issues or future 66Mhz PCI. */
651#define mdio_delay() inl(mdio_addr)
652
653/* Read and write the MII registers using software-generated serial
654 MDIO protocol. It is just different enough from the EEPROM protocol
655 to not share code. The maxium data clock rate is 2.5 Mhz. */
656#define MDIO_SHIFT_CLK 0x10000
657#define MDIO_DATA_WRITE0 0x00000
658#define MDIO_DATA_WRITE1 0x20000
659#define MDIO_ENB 0x00000 /* Ignore the 0x02000 databook setting. */
660#define MDIO_ENB_IN 0x40000
661#define MDIO_DATA_READ 0x80000
662
663static int mdio_read(struct net_device *dev, int phy_id, int location)
664{
665 int i;
666 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
667 int retval = 0;
668 long ioaddr = dev->base_addr;
669 long mdio_addr = ioaddr + CSR9;
670
671 /* Establish sync by sending at least 32 logic ones. */
672 for (i = 32; i >= 0; i--) {
673 outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
674 mdio_delay();
675 outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
676 mdio_delay();
677 }
678 /* Shift the read command bits out. */
679 for (i = 15; i >= 0; i--) {
680 int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
681
682 outl(MDIO_ENB | dataval, mdio_addr);
683 mdio_delay();
684 outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
685 mdio_delay();
686 }
687 /* Read the two transition, 16 data, and wire-idle bits. */
688 for (i = 19; i > 0; i--) {
689 outl(MDIO_ENB_IN, mdio_addr);
690 mdio_delay();
691 retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
692 outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
693 mdio_delay();
694 }
695 return (retval>>1) & 0xffff;
696}
697
698
699static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
700{
701 int i;
702 int cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
703 long ioaddr = dev->base_addr;
704 long mdio_addr = ioaddr + CSR9;
705
706 /* Establish sync by sending 32 logic ones. */
707 for (i = 32; i >= 0; i--) {
708 outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
709 mdio_delay();
710 outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
711 mdio_delay();
712 }
713 /* Shift the command bits out. */
714 for (i = 31; i >= 0; i--) {
715 int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
716 outl(MDIO_ENB | dataval, mdio_addr);
717 mdio_delay();
718 outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
719 mdio_delay();
720 }
721 /* Clear out extra bits. */
722 for (i = 2; i > 0; i--) {
723 outl(MDIO_ENB_IN, mdio_addr);
724 mdio_delay();
725 outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
726 mdio_delay();
727 }
728 return;
729}
730
731
732static void
733xircom_up(struct net_device *dev)
734{
735 struct xircom_private *tp = netdev_priv(dev);
736 long ioaddr = dev->base_addr;
737 int i;
738
739 xircom_init_ring(dev);
740 /* Clear the tx ring */
741 for (i = 0; i < TX_RING_SIZE; i++) {
742 tp->tx_skbuff[i] = NULL;
743 tp->tx_ring[i].status = 0;
744 }
745
746 if (xircom_debug > 1)
747 printk(KERN_DEBUG "%s: xircom_up() irq %d.\n", dev->name, dev->irq);
748
749 outl(virt_to_bus(tp->rx_ring), ioaddr + CSR3);
750 outl(virt_to_bus(tp->tx_ring), ioaddr + CSR4);
751
752 tp->saved_if_port = dev->if_port;
753 if (dev->if_port == 0)
754 dev->if_port = tp->default_port;
755
756 tp->csr6 = TxThresh10 /*| FullDuplexBit*/; /* XXX: why 10 and not 100? */
757
758 set_rx_mode(dev);
759
760 /* Start the chip's Tx to process setup frame. */
761 outl_CSR6(tp->csr6, ioaddr);
762 outl_CSR6(tp->csr6 | EnableTx, ioaddr);
763
764 /* Acknowledge all outstanding interrupts sources */
765 outl(xircom_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
766 /* Enable interrupts by setting the interrupt mask. */
767 outl(xircom_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
768 /* Enable Rx */
769 outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
770 /* Rx poll demand */
771 outl(0, ioaddr + CSR2);
772
773 /* Tell the net layer we're ready */
774 netif_start_queue (dev);
775
776 /* Check current media state */
777 xircom_media_change(dev);
778
779 if (xircom_debug > 2) {
780 printk(KERN_DEBUG "%s: Done xircom_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
781 dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5),
782 inl(ioaddr + CSR6));
783 }
784}
785
786
787static int
788xircom_open(struct net_device *dev)
789{
790 struct xircom_private *tp = netdev_priv(dev);
791
792 if (request_irq(dev->irq, &xircom_interrupt, IRQF_SHARED, dev->name, dev))
793 return -EAGAIN;
794
795 xircom_up(dev);
796 tp->open = 1;
797
798 return 0;
799}
800
801
802static void xircom_tx_timeout(struct net_device *dev)
803{
804 struct xircom_private *tp = netdev_priv(dev);
805 long ioaddr = dev->base_addr;
806
807 if (media_cap[dev->if_port] & MediaIsMII) {
808 /* Do nothing -- the media monitor should handle this. */
809 if (xircom_debug > 1)
810 printk(KERN_WARNING "%s: Transmit timeout using MII device.\n",
811 dev->name);
812 }
813
814#if defined(way_too_many_messages)
815 if (xircom_debug > 3) {
816 int i;
817 for (i = 0; i < RX_RING_SIZE; i++) {
818 u8 *buf = (u8 *)(tp->rx_ring[i].buffer1);
819 int j;
820 printk(KERN_DEBUG "%2d: %8.8x %8.8x %8.8x %8.8x "
821 "%2.2x %2.2x %2.2x.\n",
822 i, (unsigned int)tp->rx_ring[i].status,
823 (unsigned int)tp->rx_ring[i].length,
824 (unsigned int)tp->rx_ring[i].buffer1,
825 (unsigned int)tp->rx_ring[i].buffer2,
826 buf[0], buf[1], buf[2]);
827 for (j = 0; buf[j] != 0xee && j < 1600; j++)
828 if (j < 100) printk(" %2.2x", buf[j]);
829 printk(" j=%d.\n", j);
830 }
831 printk(KERN_DEBUG " Rx ring %8.8x: ", (int)tp->rx_ring);
832 for (i = 0; i < RX_RING_SIZE; i++)
833 printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
834 printk("\n" KERN_DEBUG " Tx ring %8.8x: ", (int)tp->tx_ring);
835 for (i = 0; i < TX_RING_SIZE; i++)
836 printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
837 printk("\n");
838 }
839#endif
840
841 /* Stop and restart the chip's Tx/Rx processes . */
842 outl_CSR6(tp->csr6 | EnableRx, ioaddr);
843 outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
844 /* Trigger an immediate transmit demand. */
845 outl(0, ioaddr + CSR1);
846
847 dev->trans_start = jiffies;
848 netif_wake_queue (dev);
849 tp->stats.tx_errors++;
850}
851
852
853/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
854static void xircom_init_ring(struct net_device *dev)
855{
856 struct xircom_private *tp = netdev_priv(dev);
857 int i;
858
859 tp->tx_full = 0;
860 tp->cur_rx = tp->cur_tx = 0;
861 tp->dirty_rx = tp->dirty_tx = 0;
862
863 for (i = 0; i < RX_RING_SIZE; i++) {
864 tp->rx_ring[i].status = 0;
865 tp->rx_ring[i].length = PKT_BUF_SZ;
866 tp->rx_ring[i].buffer2 = virt_to_bus(&tp->rx_ring[i+1]);
867 tp->rx_skbuff[i] = NULL;
868 }
869 /* Mark the last entry as wrapping the ring. */
870 tp->rx_ring[i-1].length = PKT_BUF_SZ | Rx1RingWrap;
871 tp->rx_ring[i-1].buffer2 = virt_to_bus(&tp->rx_ring[0]);
872
873 for (i = 0; i < RX_RING_SIZE; i++) {
874 /* Note the receive buffer must be longword aligned.
875 dev_alloc_skb() provides 16 byte alignment. But do *not*
876 use skb_reserve() to align the IP header! */
877 struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
878 tp->rx_skbuff[i] = skb;
879 if (skb == NULL)
880 break;
881 skb->dev = dev; /* Mark as being used by this device. */
882 tp->rx_ring[i].status = Rx0DescOwned; /* Owned by Xircom chip */
883 tp->rx_ring[i].buffer1 = virt_to_bus(skb->data);
884 }
885 tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
886
887 /* The Tx buffer descriptor is filled in as needed, but we
888 do need to clear the ownership bit. */
889 for (i = 0; i < TX_RING_SIZE; i++) {
890 tp->tx_skbuff[i] = NULL;
891 tp->tx_ring[i].status = 0;
892 tp->tx_ring[i].buffer2 = virt_to_bus(&tp->tx_ring[i+1]);
893 if (tp->chip_id == X3201_3)
894 tp->tx_aligned_skbuff[i] = dev_alloc_skb(PKT_BUF_SZ);
895 }
896 tp->tx_ring[i-1].buffer2 = virt_to_bus(&tp->tx_ring[0]);
897}
898
899
900static int
901xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
902{
903 struct xircom_private *tp = netdev_priv(dev);
904 int entry;
905 u32 flag;
906
907 /* Caution: the write order is important here, set the base address
908 with the "ownership" bits last. */
909
910 /* Calculate the next Tx descriptor entry. */
911 entry = tp->cur_tx % TX_RING_SIZE;
912
913 tp->tx_skbuff[entry] = skb;
914 if (tp->chip_id == X3201_3) {
915 skb_copy_from_linear_data(skb,
916 tp->tx_aligned_skbuff[entry]->data,
917 skb->len);
918 tp->tx_ring[entry].buffer1 = virt_to_bus(tp->tx_aligned_skbuff[entry]->data);
919 } else
920 tp->tx_ring[entry].buffer1 = virt_to_bus(skb->data);
921
922 if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
923 flag = Tx1WholePkt; /* No interrupt */
924 } else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) {
925 flag = Tx1WholePkt | Tx1ComplIntr; /* Tx-done intr. */
926 } else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) {
927 flag = Tx1WholePkt; /* No Tx-done intr. */
928 } else {
929 /* Leave room for set_rx_mode() to fill entries. */
930 flag = Tx1WholePkt | Tx1ComplIntr; /* Tx-done intr. */
931 tp->tx_full = 1;
932 }
933 if (entry == TX_RING_SIZE - 1)
934 flag |= Tx1WholePkt | Tx1ComplIntr | Tx1RingWrap;
935
936 tp->tx_ring[entry].length = skb->len | flag;
937 tp->tx_ring[entry].status = Tx0DescOwned; /* Pass ownership to the chip. */
938 tp->cur_tx++;
939 if (tp->tx_full)
940 netif_stop_queue (dev);
941 else
942 netif_wake_queue (dev);
943
944 /* Trigger an immediate transmit demand. */
945 outl(0, dev->base_addr + CSR1);
946
947 dev->trans_start = jiffies;
948
949 return 0;
950}
951
952
953static void xircom_media_change(struct net_device *dev)
954{
955 struct xircom_private *tp = netdev_priv(dev);
956 long ioaddr = dev->base_addr;
957 u16 reg0, reg1, reg4, reg5;
958 u32 csr6 = inl(ioaddr + CSR6), newcsr6;
959
960 /* reset status first */
961 mdio_read(dev, tp->phys[0], MII_BMCR);
962 mdio_read(dev, tp->phys[0], MII_BMSR);
963
964 reg0 = mdio_read(dev, tp->phys[0], MII_BMCR);
965 reg1 = mdio_read(dev, tp->phys[0], MII_BMSR);
966
967 if (reg1 & BMSR_LSTATUS) {
968 /* link is up */
969 if (reg0 & BMCR_ANENABLE) {
970 /* autonegotiation is enabled */
971 reg4 = mdio_read(dev, tp->phys[0], MII_ADVERTISE);
972 reg5 = mdio_read(dev, tp->phys[0], MII_LPA);
973 if (reg4 & ADVERTISE_100FULL && reg5 & LPA_100FULL) {
974 tp->speed100 = 1;
975 tp->full_duplex = 1;
976 } else if (reg4 & ADVERTISE_100HALF && reg5 & LPA_100HALF) {
977 tp->speed100 = 1;
978 tp->full_duplex = 0;
979 } else if (reg4 & ADVERTISE_10FULL && reg5 & LPA_10FULL) {
980 tp->speed100 = 0;
981 tp->full_duplex = 1;
982 } else {
983 tp->speed100 = 0;
984 tp->full_duplex = 0;
985 }
986 } else {
987 /* autonegotiation is disabled */
988 if (reg0 & BMCR_SPEED100)
989 tp->speed100 = 1;
990 else
991 tp->speed100 = 0;
992 if (reg0 & BMCR_FULLDPLX)
993 tp->full_duplex = 1;
994 else
995 tp->full_duplex = 0;
996 }
997 printk(KERN_DEBUG "%s: Link is up, running at %sMbit %s-duplex\n",
998 dev->name,
999 tp->speed100 ? "100" : "10",
1000 tp->full_duplex ? "full" : "half");
1001 netif_carrier_on(dev);
1002 newcsr6 = csr6 & ~FullDuplexBit;
1003 if (tp->full_duplex)
1004 newcsr6 |= FullDuplexBit;
1005 if (newcsr6 != csr6)
1006 outl_CSR6(newcsr6, ioaddr + CSR6);
1007 } else {
1008 printk(KERN_DEBUG "%s: Link is down\n", dev->name);
1009 netif_carrier_off(dev);
1010 }
1011}
1012
1013
1014static void check_duplex(struct net_device *dev)
1015{
1016 struct xircom_private *tp = netdev_priv(dev);
1017 u16 reg0;
1018
1019 mdio_write(dev, tp->phys[0], MII_BMCR, BMCR_RESET);
1020 udelay(500);
1021 while (mdio_read(dev, tp->phys[0], MII_BMCR) & BMCR_RESET);
1022
1023 reg0 = mdio_read(dev, tp->phys[0], MII_BMCR);
1024 mdio_write(dev, tp->phys[0], MII_ADVERTISE, tp->advertising[0]);
1025
1026 if (tp->autoneg) {
1027 reg0 &= ~(BMCR_SPEED100 | BMCR_FULLDPLX);
1028 reg0 |= BMCR_ANENABLE | BMCR_ANRESTART;
1029 } else {
1030 reg0 &= ~(BMCR_ANENABLE | BMCR_ANRESTART);
1031 if (tp->speed100)
1032 reg0 |= BMCR_SPEED100;
1033 if (tp->full_duplex)
1034 reg0 |= BMCR_FULLDPLX;
1035 printk(KERN_DEBUG "%s: Link forced to %sMbit %s-duplex\n",
1036 dev->name,
1037 tp->speed100 ? "100" : "10",
1038 tp->full_duplex ? "full" : "half");
1039 }
1040 mdio_write(dev, tp->phys[0], MII_BMCR, reg0);
1041}
1042
1043
1044/* The interrupt handler does all of the Rx thread work and cleans up
1045 after the Tx thread. */
1046static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
1047{
1048 struct net_device *dev = dev_instance;
1049 struct xircom_private *tp = netdev_priv(dev);
1050 long ioaddr = dev->base_addr;
1051 int csr5, work_budget = max_interrupt_work;
1052 int handled = 0;
1053
1054 spin_lock (&tp->lock);
1055
1056 do {
1057 csr5 = inl(ioaddr + CSR5);
1058 /* Acknowledge all of the current interrupt sources ASAP. */
1059 outl(csr5 & 0x0001ffff, ioaddr + CSR5);
1060
1061 if (xircom_debug > 4)
1062 printk(KERN_DEBUG "%s: interrupt csr5=%#8.8x new csr5=%#8.8x.\n",
1063 dev->name, csr5, inl(dev->base_addr + CSR5));
1064
1065 if (csr5 == 0xffffffff)
1066 break; /* all bits set, assume PCMCIA card removed */
1067
1068 if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
1069 break;
1070
1071 handled = 1;
1072
1073 if (csr5 & (RxIntr | RxNoBuf))
1074 work_budget -= xircom_rx(dev);
1075
1076 if (csr5 & (TxNoBuf | TxDied | TxIntr)) {
1077 unsigned int dirty_tx;
1078
1079 for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0;
1080 dirty_tx++) {
1081 int entry = dirty_tx % TX_RING_SIZE;
1082 int status = tp->tx_ring[entry].status;
1083
1084 if (status < 0)
1085 break; /* It still hasn't been Txed */
1086 /* Check for Rx filter setup frames. */
1087 if (tp->tx_skbuff[entry] == NULL)
1088 continue;
1089
1090 if (status & Tx0DescError) {
1091 /* There was an major error, log it. */
1092#ifndef final_version
1093 if (xircom_debug > 1)
1094 printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
1095 dev->name, status);
1096#endif
1097 tp->stats.tx_errors++;
1098 if (status & Tx0ManyColl) {
1099 tp->stats.tx_aborted_errors++;
1100 }
1101 if (status & Tx0NoCarrier) tp->stats.tx_carrier_errors++;
1102 if (status & Tx0LateColl) tp->stats.tx_window_errors++;
1103 if (status & Tx0Underflow) tp->stats.tx_fifo_errors++;
1104 } else {
1105 tp->stats.tx_bytes += tp->tx_ring[entry].length & 0x7ff;
1106 tp->stats.collisions += (status >> 3) & 15;
1107 tp->stats.tx_packets++;
1108 }
1109
1110 /* Free the original skb. */
1111 dev_kfree_skb_irq(tp->tx_skbuff[entry]);
1112 tp->tx_skbuff[entry] = NULL;
1113 }
1114
1115#ifndef final_version
1116 if (tp->cur_tx - dirty_tx > TX_RING_SIZE) {
1117 printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
1118 dev->name, dirty_tx, tp->cur_tx, tp->tx_full);
1119 dirty_tx += TX_RING_SIZE;
1120 }
1121#endif
1122
1123 if (tp->tx_full &&
1124 tp->cur_tx - dirty_tx < TX_RING_SIZE - 2)
1125 /* The ring is no longer full */
1126 tp->tx_full = 0;
1127
1128 if (tp->tx_full)
1129 netif_stop_queue (dev);
1130 else
1131 netif_wake_queue (dev);
1132
1133 tp->dirty_tx = dirty_tx;
1134 if (csr5 & TxDied) {
1135 if (xircom_debug > 2)
1136 printk(KERN_WARNING "%s: The transmitter stopped."
1137 " CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
1138 dev->name, csr5, inl(ioaddr + CSR6), tp->csr6);
1139 outl_CSR6(tp->csr6 | EnableRx, ioaddr);
1140 outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
1141 }
1142 }
1143
1144 /* Log errors. */
1145 if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */
1146 if (csr5 & LinkChange)
1147 xircom_media_change(dev);
1148 if (csr5 & TxFIFOUnderflow) {
1149 if ((tp->csr6 & TxThreshMask) != TxThreshMask)
1150 tp->csr6 += (1 << TxThreshShift); /* Bump up the Tx threshold */
1151 else
1152 tp->csr6 |= TxStoreForw; /* Store-n-forward. */
1153 /* Restart the transmit process. */
1154 outl_CSR6(tp->csr6 | EnableRx, ioaddr);
1155 outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
1156 }
1157 if (csr5 & RxDied) { /* Missed a Rx frame. */
1158 tp->stats.rx_errors++;
1159 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
1160 outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
1161 }
1162 /* Clear all error sources, included undocumented ones! */
1163 outl(0x0800f7ba, ioaddr + CSR5);
1164 }
1165 if (--work_budget < 0) {
1166 if (xircom_debug > 1)
1167 printk(KERN_WARNING "%s: Too much work during an interrupt, "
1168 "csr5=0x%8.8x.\n", dev->name, csr5);
1169 /* Acknowledge all interrupt sources. */
1170 outl(0x8001ffff, ioaddr + CSR5);
1171 break;
1172 }
1173 } while (1);
1174
1175 if (xircom_debug > 3)
1176 printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
1177 dev->name, inl(ioaddr + CSR5));
1178
1179 spin_unlock (&tp->lock);
1180 return IRQ_RETVAL(handled);
1181}
1182
1183
1184static int
1185xircom_rx(struct net_device *dev)
1186{
1187 struct xircom_private *tp = netdev_priv(dev);
1188 int entry = tp->cur_rx % RX_RING_SIZE;
1189 int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
1190 int work_done = 0;
1191
1192 if (xircom_debug > 4)
1193 printk(KERN_DEBUG " In xircom_rx(), entry %d %8.8x.\n", entry,
1194 tp->rx_ring[entry].status);
1195 /* If we own the next entry, it's a new packet. Send it up. */
1196 while (tp->rx_ring[entry].status >= 0) {
1197 s32 status = tp->rx_ring[entry].status;
1198
1199 if (xircom_debug > 5)
1200 printk(KERN_DEBUG " In xircom_rx(), entry %d %8.8x.\n", entry,
1201 tp->rx_ring[entry].status);
1202 if (--rx_work_limit < 0)
1203 break;
1204 if ((status & 0x38008300) != 0x0300) {
1205 if ((status & 0x38000300) != 0x0300) {
1206 /* Ignore earlier buffers. */
1207 if ((status & 0xffff) != 0x7fff) {
1208 if (xircom_debug > 1)
1209 printk(KERN_WARNING "%s: Oversized Ethernet frame "
1210 "spanned multiple buffers, status %8.8x!\n",
1211 dev->name, status);
1212 tp->stats.rx_length_errors++;
1213 }
1214 } else if (status & Rx0DescError) {
1215 /* There was a fatal error. */
1216 if (xircom_debug > 2)
1217 printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
1218 dev->name, status);
1219 tp->stats.rx_errors++; /* end of a packet.*/
1220 if (status & (Rx0Runt | Rx0HugeFrame)) tp->stats.rx_length_errors++;
1221 if (status & Rx0CRCError) tp->stats.rx_crc_errors++;
1222 }
1223 } else {
1224 /* Omit the four octet CRC from the length. */
1225 short pkt_len = ((status >> 16) & 0x7ff) - 4;
1226 struct sk_buff *skb;
1227
1228#ifndef final_version
1229 if (pkt_len > 1518) {
1230 printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
1231 dev->name, pkt_len, pkt_len);
1232 pkt_len = 1518;
1233 tp->stats.rx_length_errors++;
1234 }
1235#endif
1236 /* Check if the packet is long enough to accept without copying
1237 to a minimally-sized skbuff. */
1238 if (pkt_len < rx_copybreak
1239 && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
1240 skb_reserve(skb, 2); /* 16 byte align the IP header */
1241#if ! defined(__alpha__)
1242 skb_copy_to_linear_data(skb, bus_to_virt(tp->rx_ring[entry].buffer1),
1243 pkt_len);
1244 skb_put(skb, pkt_len);
1245#else
1246 memcpy(skb_put(skb, pkt_len),
1247 bus_to_virt(tp->rx_ring[entry].buffer1), pkt_len);
1248#endif
1249 work_done++;
1250 } else { /* Pass up the skb already on the Rx ring. */
1251 skb_put(skb = tp->rx_skbuff[entry], pkt_len);
1252 tp->rx_skbuff[entry] = NULL;
1253 }
1254 skb->protocol = eth_type_trans(skb, dev);
1255 netif_rx(skb);
1256 dev->last_rx = jiffies;
1257 tp->stats.rx_packets++;
1258 tp->stats.rx_bytes += pkt_len;
1259 }
1260 entry = (++tp->cur_rx) % RX_RING_SIZE;
1261 }
1262
1263 /* Refill the Rx ring buffers. */
1264 for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
1265 entry = tp->dirty_rx % RX_RING_SIZE;
1266 if (tp->rx_skbuff[entry] == NULL) {
1267 struct sk_buff *skb;
1268 skb = tp->rx_skbuff[entry] = dev_alloc_skb(PKT_BUF_SZ);
1269 if (skb == NULL)
1270 break;
1271 skb->dev = dev; /* Mark as being used by this device. */
1272 tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data);
1273 work_done++;
1274 }
1275 tp->rx_ring[entry].status = Rx0DescOwned;
1276 }
1277
1278 return work_done;
1279}
1280
1281
1282static void
1283xircom_down(struct net_device *dev)
1284{
1285 long ioaddr = dev->base_addr;
1286 struct xircom_private *tp = netdev_priv(dev);
1287
1288 /* Disable interrupts by clearing the interrupt mask. */
1289 outl(0, ioaddr + CSR7);
1290 /* Stop the chip's Tx and Rx processes. */
1291 outl_CSR6(inl(ioaddr + CSR6) & ~EnableTxRx, ioaddr);
1292
1293 if (inl(ioaddr + CSR6) != 0xffffffff)
1294 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
1295
1296 dev->if_port = tp->saved_if_port;
1297}
1298
1299
1300static int
1301xircom_close(struct net_device *dev)
1302{
1303 long ioaddr = dev->base_addr;
1304 struct xircom_private *tp = netdev_priv(dev);
1305 int i;
1306
1307 if (xircom_debug > 1)
1308 printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
1309 dev->name, inl(ioaddr + CSR5));
1310
1311 netif_stop_queue(dev);
1312
1313 if (netif_device_present(dev))
1314 xircom_down(dev);
1315
1316 free_irq(dev->irq, dev);
1317
1318 /* Free all the skbuffs in the Rx queue. */
1319 for (i = 0; i < RX_RING_SIZE; i++) {
1320 struct sk_buff *skb = tp->rx_skbuff[i];
1321 tp->rx_skbuff[i] = NULL;
1322 tp->rx_ring[i].status = 0; /* Not owned by Xircom chip. */
1323 tp->rx_ring[i].length = 0;
1324 tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */
1325 if (skb) {
1326 dev_kfree_skb(skb);
1327 }
1328 }
1329 for (i = 0; i < TX_RING_SIZE; i++) {
1330 if (tp->tx_skbuff[i])
1331 dev_kfree_skb(tp->tx_skbuff[i]);
1332 tp->tx_skbuff[i] = NULL;
1333 }
1334
1335 tp->open = 0;
1336 return 0;
1337}
1338
1339
1340static struct net_device_stats *xircom_get_stats(struct net_device *dev)
1341{
1342 struct xircom_private *tp = netdev_priv(dev);
1343 long ioaddr = dev->base_addr;
1344
1345 if (netif_device_present(dev))
1346 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
1347
1348 return &tp->stats;
1349}
1350
1351static int xircom_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
1352{
1353 struct xircom_private *tp = netdev_priv(dev);
1354 ecmd->supported =
1355 SUPPORTED_10baseT_Half |
1356 SUPPORTED_10baseT_Full |
1357 SUPPORTED_100baseT_Half |
1358 SUPPORTED_100baseT_Full |
1359 SUPPORTED_Autoneg |
1360 SUPPORTED_MII;
1361
1362 ecmd->advertising = ADVERTISED_MII;
1363 if (tp->advertising[0] & ADVERTISE_10HALF)
1364 ecmd->advertising |= ADVERTISED_10baseT_Half;
1365 if (tp->advertising[0] & ADVERTISE_10FULL)
1366 ecmd->advertising |= ADVERTISED_10baseT_Full;
1367 if (tp->advertising[0] & ADVERTISE_100HALF)
1368 ecmd->advertising |= ADVERTISED_100baseT_Half;
1369 if (tp->advertising[0] & ADVERTISE_100FULL)
1370 ecmd->advertising |= ADVERTISED_100baseT_Full;
1371 if (tp->autoneg) {
1372 ecmd->advertising |= ADVERTISED_Autoneg;
1373 ecmd->autoneg = AUTONEG_ENABLE;
1374 } else
1375 ecmd->autoneg = AUTONEG_DISABLE;
1376
1377 ecmd->port = PORT_MII;
1378 ecmd->transceiver = XCVR_INTERNAL;
1379 ecmd->phy_address = tp->phys[0];
1380 ecmd->speed = tp->speed100 ? SPEED_100 : SPEED_10;
1381 ecmd->duplex = tp->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1382 ecmd->maxtxpkt = TX_RING_SIZE / 2;
1383 ecmd->maxrxpkt = 0;
1384 return 0;
1385}
1386
1387static int xircom_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
1388{
1389 struct xircom_private *tp = netdev_priv(dev);
1390 u16 autoneg, speed100, full_duplex;
1391
1392 autoneg = (ecmd->autoneg == AUTONEG_ENABLE);
1393 speed100 = (ecmd->speed == SPEED_100);
1394 full_duplex = (ecmd->duplex == DUPLEX_FULL);
1395
1396 tp->autoneg = autoneg;
1397 if (speed100 != tp->speed100 ||
1398 full_duplex != tp->full_duplex) {
1399 tp->speed100 = speed100;
1400 tp->full_duplex = full_duplex;
1401 /* change advertising bits */
1402 tp->advertising[0] &= ~(ADVERTISE_10HALF |
1403 ADVERTISE_10FULL |
1404 ADVERTISE_100HALF |
1405 ADVERTISE_100FULL |
1406 ADVERTISE_100BASE4);
1407 if (speed100) {
1408 if (full_duplex)
1409 tp->advertising[0] |= ADVERTISE_100FULL;
1410 else
1411 tp->advertising[0] |= ADVERTISE_100HALF;
1412 } else {
1413 if (full_duplex)
1414 tp->advertising[0] |= ADVERTISE_10FULL;
1415 else
1416 tp->advertising[0] |= ADVERTISE_10HALF;
1417 }
1418 }
1419 check_duplex(dev);
1420 return 0;
1421}
1422
1423static void xircom_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1424{
1425 struct xircom_private *tp = netdev_priv(dev);
1426 strcpy(info->driver, DRV_NAME);
1427 strcpy(info->version, DRV_VERSION);
1428 strcpy(info->bus_info, pci_name(tp->pdev));
1429}
1430
1431static const struct ethtool_ops ops = {
1432 .get_settings = xircom_get_settings,
1433 .set_settings = xircom_set_settings,
1434 .get_drvinfo = xircom_get_drvinfo,
1435};
1436
1437/* Provide ioctl() calls to examine the MII xcvr state. */
1438static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1439{
1440 struct xircom_private *tp = netdev_priv(dev);
1441 u16 *data = (u16 *)&rq->ifr_ifru;
1442 int phy = tp->phys[0] & 0x1f;
1443 unsigned long flags;
1444
1445 switch(cmd) {
1446 /* Legacy mii-diag interface */
1447 case SIOCGMIIPHY: /* Get address of MII PHY in use. */
1448 if (tp->mii_cnt)
1449 data[0] = phy;
1450 else
1451 return -ENODEV;
1452 return 0;
1453 case SIOCGMIIREG: /* Read MII PHY register. */
1454 save_flags(flags);
1455 cli();
1456 data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
1457 restore_flags(flags);
1458 return 0;
1459 case SIOCSMIIREG: /* Write MII PHY register. */
1460 if (!capable(CAP_NET_ADMIN))
1461 return -EPERM;
1462 save_flags(flags);
1463 cli();
1464 if (data[0] == tp->phys[0]) {
1465 u16 value = data[2];
1466 switch (data[1]) {
1467 case 0:
1468 if (value & (BMCR_RESET | BMCR_ANENABLE))
1469 /* Autonegotiation. */
1470 tp->autoneg = 1;
1471 else {
1472 tp->full_duplex = (value & BMCR_FULLDPLX) ? 1 : 0;
1473 tp->autoneg = 0;
1474 }
1475 break;
1476 case 4:
1477 tp->advertising[0] = value;
1478 break;
1479 }
1480 check_duplex(dev);
1481 }
1482 mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
1483 restore_flags(flags);
1484 return 0;
1485 default:
1486 return -EOPNOTSUPP;
1487 }
1488
1489 return -EOPNOTSUPP;
1490}
1491
1492/* Set or clear the multicast filter for this adaptor.
1493 Note that we only use exclusion around actually queueing the
1494 new frame, not around filling tp->setup_frame. This is non-deterministic
1495 when re-entered but still correct. */
1496static void set_rx_mode(struct net_device *dev)
1497{
1498 struct xircom_private *tp = netdev_priv(dev);
1499 struct dev_mc_list *mclist;
1500 long ioaddr = dev->base_addr;
1501 int csr6 = inl(ioaddr + CSR6);
1502 u16 *eaddrs, *setup_frm;
1503 u32 tx_flags;
1504 int i;
1505
1506 tp->csr6 &= ~(AllMultiBit | PromiscBit | HashFilterBit);
1507 csr6 &= ~(AllMultiBit | PromiscBit | HashFilterBit);
1508 if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
1509 tp->csr6 |= PromiscBit;
1510 csr6 |= PromiscBit;
1511 goto out;
1512 }
1513
1514 if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) {
1515 /* Too many to filter well -- accept all multicasts. */
1516 tp->csr6 |= AllMultiBit;
1517 csr6 |= AllMultiBit;
1518 goto out;
1519 }
1520
1521 tx_flags = Tx1WholePkt | Tx1SetupPkt | PKT_SETUP_SZ;
1522
1523 /* Note that only the low-address shortword of setup_frame is valid! */
1524 setup_frm = tp->setup_frame;
1525 mclist = dev->mc_list;
1526
1527 /* Fill the first entry with our physical address. */
1528 eaddrs = (u16 *)dev->dev_addr;
1529 *setup_frm = cpu_to_le16(eaddrs[0]); setup_frm += 2;
1530 *setup_frm = cpu_to_le16(eaddrs[1]); setup_frm += 2;
1531 *setup_frm = cpu_to_le16(eaddrs[2]); setup_frm += 2;
1532
1533 if (dev->mc_count > 14) { /* Must use a multicast hash table. */
1534 u32 *hash_table = (u32 *)(tp->setup_frame + 4 * 12);
1535 u32 hash, hash2;
1536
1537 tx_flags |= Tx1HashSetup;
1538 tp->csr6 |= HashFilterBit;
1539 csr6 |= HashFilterBit;
1540
1541 /* Fill the unused 3 entries with the broadcast address.
1542 At least one entry *must* contain the broadcast address!!!*/
1543 for (i = 0; i < 3; i++) {
1544 *setup_frm = 0xffff; setup_frm += 2;
1545 *setup_frm = 0xffff; setup_frm += 2;
1546 *setup_frm = 0xffff; setup_frm += 2;
1547 }
1548
1549 /* Truly brain-damaged hash filter layout */
1550 /* XXX: not sure if I should take the last or the first 9 bits */
1551 for (i = 0; i < dev->mc_count; i++, mclist = mclist->next) {
1552 u32 *hptr;
1553 hash = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff;
1554 if (hash < 384) {
1555 hash2 = hash + ((hash >> 4) << 4) +
1556 ((hash >> 5) << 5);
1557 } else {
1558 hash -= 384;
1559 hash2 = 64 + hash + (hash >> 4) * 80;
1560 }
1561 hptr = &hash_table[hash2 & ~0x1f];
1562 *hptr |= cpu_to_le32(1 << (hash2 & 0x1f));
1563 }
1564 } else {
1565 /* We have <= 14 mcast addresses so we can use Xircom's
1566 wonderful 16-address perfect filter. */
1567 for (i = 0; i < dev->mc_count; i++, mclist = mclist->next) {
1568 eaddrs = (u16 *)mclist->dmi_addr;
1569 *setup_frm = cpu_to_le16(eaddrs[0]); setup_frm += 2;
1570 *setup_frm = cpu_to_le16(eaddrs[1]); setup_frm += 2;
1571 *setup_frm = cpu_to_le16(eaddrs[2]); setup_frm += 2;
1572 }
1573 /* Fill the unused entries with the broadcast address.
1574 At least one entry *must* contain the broadcast address!!!*/
1575 for (; i < 15; i++) {
1576 *setup_frm = 0xffff; setup_frm += 2;
1577 *setup_frm = 0xffff; setup_frm += 2;
1578 *setup_frm = 0xffff; setup_frm += 2;
1579 }
1580 }
1581
1582 /* Now add this frame to the Tx list. */
1583 if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
1584 /* Same setup recently queued, we need not add it. */
1585 /* XXX: Huh? All it means is that the Tx list is full...*/
1586 } else {
1587 unsigned long flags;
1588 unsigned int entry;
1589 int dummy = -1;
1590
1591 save_flags(flags); cli();
1592 entry = tp->cur_tx++ % TX_RING_SIZE;
1593
1594 if (entry != 0) {
1595 /* Avoid a chip errata by prefixing a dummy entry. */
1596 tp->tx_skbuff[entry] = NULL;
1597 tp->tx_ring[entry].length =
1598 (entry == TX_RING_SIZE - 1) ? Tx1RingWrap : 0;
1599 tp->tx_ring[entry].buffer1 = 0;
1600 /* race with chip, set Tx0DescOwned later */
1601 dummy = entry;
1602 entry = tp->cur_tx++ % TX_RING_SIZE;
1603 }
1604
1605 tp->tx_skbuff[entry] = NULL;
1606 /* Put the setup frame on the Tx list. */
1607 if (entry == TX_RING_SIZE - 1)
1608 tx_flags |= Tx1RingWrap; /* Wrap ring. */
1609 tp->tx_ring[entry].length = tx_flags;
1610 tp->tx_ring[entry].buffer1 = virt_to_bus(tp->setup_frame);
1611 tp->tx_ring[entry].status = Tx0DescOwned;
1612 if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
1613 tp->tx_full = 1;
1614 netif_stop_queue (dev);
1615 }
1616 if (dummy >= 0)
1617 tp->tx_ring[dummy].status = Tx0DescOwned;
1618 restore_flags(flags);
1619 /* Trigger an immediate transmit demand. */
1620 outl(0, ioaddr + CSR1);
1621 }
1622
1623out:
1624 outl_CSR6(csr6, ioaddr);
1625}
1626
1627
1628static struct pci_device_id xircom_pci_table[] = {
1629 { 0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, X3201_3 },
1630 {0},
1631};
1632MODULE_DEVICE_TABLE(pci, xircom_pci_table);
1633
1634
1635#ifdef CONFIG_PM
1636static int xircom_suspend(struct pci_dev *pdev, pm_message_t state)
1637{
1638 struct net_device *dev = pci_get_drvdata(pdev);
1639 struct xircom_private *tp = netdev_priv(dev);
1640 printk(KERN_INFO "xircom_suspend(%s)\n", dev->name);
1641 if (tp->open)
1642 xircom_down(dev);
1643
1644 pci_save_state(pdev);
1645 pci_disable_device(pdev);
1646 pci_set_power_state(pdev, 3);
1647
1648 return 0;
1649}
1650
1651
1652static int xircom_resume(struct pci_dev *pdev)
1653{
1654 struct net_device *dev = pci_get_drvdata(pdev);
1655 struct xircom_private *tp = netdev_priv(dev);
1656 printk(KERN_INFO "xircom_resume(%s)\n", dev->name);
1657
1658 pci_set_power_state(pdev,0);
1659 pci_enable_device(pdev);
1660 pci_restore_state(pdev);
1661
1662 /* Bring the chip out of sleep mode.
1663 Caution: Snooze mode does not work with some boards! */
1664 if (xircom_tbl[tp->chip_id].flags & HAS_ACPI)
1665 pci_write_config_dword(tp->pdev, PCI_POWERMGMT, 0);
1666
1667 transceiver_voodoo(dev);
1668 if (xircom_tbl[tp->chip_id].flags & HAS_MII)
1669 check_duplex(dev);
1670
1671 if (tp->open)
1672 xircom_up(dev);
1673 return 0;
1674}
1675#endif /* CONFIG_PM */
1676
1677
1678static void __devexit xircom_remove_one(struct pci_dev *pdev)
1679{
1680 struct net_device *dev = pci_get_drvdata(pdev);
1681
1682 printk(KERN_INFO "xircom_remove_one(%s)\n", dev->name);
1683 unregister_netdev(dev);
1684 pci_release_regions(pdev);
1685 free_netdev(dev);
1686 pci_set_drvdata(pdev, NULL);
1687}
1688
1689
1690static struct pci_driver xircom_driver = {
1691 .name = DRV_NAME,
1692 .id_table = xircom_pci_table,
1693 .probe = xircom_init_one,
1694 .remove = __devexit_p(xircom_remove_one),
1695#ifdef CONFIG_PM
1696 .suspend = xircom_suspend,
1697 .resume = xircom_resume
1698#endif /* CONFIG_PM */
1699};
1700
1701
1702static int __init xircom_init(void)
1703{
1704/* when a module, this is printed whether or not devices are found in probe */
1705#ifdef MODULE
1706 printk(version);
1707#endif
1708 return pci_register_driver(&xircom_driver);
1709}
1710
1711
1712static void __exit xircom_exit(void)
1713{
1714 pci_unregister_driver(&xircom_driver);
1715}
1716
1717module_init(xircom_init)
1718module_exit(xircom_exit)
1719
1720/*
1721 * Local variables:
1722 * c-indent-level: 4
1723 * c-basic-offset: 4
1724 * tab-width: 4
1725 * End:
1726 */
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index eada69dec4fe..a7745c82b4ae 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -5,22 +5,25 @@ config LCS
5 tristate "Lan Channel Station Interface" 5 tristate "Lan Channel Station Interface"
6 depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI) 6 depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI)
7 help 7 help
8 Select this option if you want to use LCS networking on IBM S/390 8 Select this option if you want to use LCS networking on IBM System z.
9 or zSeries. This device driver supports Token Ring (IEEE 802.5), 9 This device driver supports Token Ring (IEEE 802.5),
10 FDDI (IEEE 802.7) and Ethernet. 10 FDDI (IEEE 802.7) and Ethernet.
11 This option is also available as a module which will be 11 To compile as a module, choose M. The module name is lcs.ko.
12 called lcs.ko. If you do not know what it is, it's safe to say "Y". 12 If you do not know what it is, it's safe to choose Y.
13 13
14config CTC 14config CTCM
15 tristate "CTC device support" 15 tristate "CTC and MPC SNA device support"
16 depends on CCW && NETDEVICES 16 depends on CCW && NETDEVICES
17 help 17 help
18 Select this option if you want to use channel-to-channel networking 18 Select this option if you want to use channel-to-channel
19 on IBM S/390 or zSeries. This device driver supports real CTC 19 point-to-point networking on IBM System z.
20 coupling using ESCON. It also supports virtual CTCs when running 20 This device driver supports real CTC coupling using ESCON.
21 under VM. It will use the channel device configuration if this is 21 It also supports virtual CTCs when running under VM.
22 available. This option is also available as a module which will be 22 This driver also supports channel-to-channel MPC SNA devices.
23 called ctc.ko. If you do not know what it is, it's safe to say "Y". 23 MPC is an SNA protocol device used by Communication Server for Linux.
24 To compile as a module, choose M. The module name is ctcm.ko.
25 To compile into the kernel, choose Y.
26 If you do not need any channel-to-channel connection, choose N.
24 27
25config NETIUCV 28config NETIUCV
26 tristate "IUCV network device support (VM only)" 29 tristate "IUCV network device support (VM only)"
@@ -29,9 +32,9 @@ config NETIUCV
29 Select this option if you want to use inter-user communication 32 Select this option if you want to use inter-user communication
30 vehicle networking under VM or VIF. It enables a fast communication 33 vehicle networking under VM or VIF. It enables a fast communication
31 link between VM guests. Using ifconfig a point-to-point connection 34 link between VM guests. Using ifconfig a point-to-point connection
32 can be established to the Linux for zSeries and S7390 system 35 can be established to the Linux on IBM System z
33 running on the other VM guest. This option is also available 36 running on the other VM guest. To compile as a module, choose M.
34 as a module which will be called netiucv.ko. If unsure, say "Y". 37 The module name is netiucv.ko. If unsure, choose Y.
35 38
36config SMSGIUCV 39config SMSGIUCV
37 tristate "IUCV special message support (VM only)" 40 tristate "IUCV special message support (VM only)"
@@ -47,43 +50,46 @@ config CLAW
47 This driver supports channel attached CLAW devices. 50 This driver supports channel attached CLAW devices.
48 CLAW is Common Link Access for Workstation. Common devices 51 CLAW is Common Link Access for Workstation. Common devices
49 that use CLAW are RS/6000s, Cisco Routers (CIP) and 3172 devices. 52 that use CLAW are RS/6000s, Cisco Routers (CIP) and 3172 devices.
50 To compile as a module choose M here: The module will be called 53 To compile as a module, choose M. The module name is claw.ko.
51 claw.ko to compile into the kernel choose Y 54 To compile into the kernel, choose Y.
52 55
53config QETH 56config QETH
54 tristate "Gigabit Ethernet device support" 57 tristate "Gigabit Ethernet device support"
55 depends on CCW && NETDEVICES && IP_MULTICAST && QDIO 58 depends on CCW && NETDEVICES && IP_MULTICAST && QDIO
56 help 59 help
57 This driver supports the IBM S/390 and zSeries OSA Express adapters 60 This driver supports the IBM System z OSA Express adapters
58 in QDIO mode (all media types), HiperSockets interfaces and VM GuestLAN 61 in QDIO mode (all media types), HiperSockets interfaces and VM GuestLAN
59 interfaces in QDIO and HIPER mode. 62 interfaces in QDIO and HIPER mode.
60 63
61 For details please refer to the documentation provided by IBM at 64 For details please refer to the documentation provided by IBM at
62 <http://www10.software.ibm.com/developerworks/opensource/linux390> 65 <http://www.ibm.com/developerworks/linux/linux390>
63 66
64 To compile this driver as a module, choose M here: the 67 To compile this driver as a module, choose M.
65 module will be called qeth.ko. 68 The module name is qeth.ko.
66 69
70config QETH_L2
71 tristate "qeth layer 2 device support"
72 depends on QETH
73 help
74 Select this option to be able to run qeth devices in layer 2 mode.
75 To compile as a module, choose M. The module name is qeth_l2.ko.
76 If unsure, choose y.
67 77
68comment "Gigabit Ethernet default settings" 78config QETH_L3
69 depends on QETH 79 tristate "qeth layer 3 device support"
80 depends on QETH
81 help
82 Select this option to be able to run qeth devices in layer 3 mode.
83 To compile as a module choose M. The module name is qeth_l3.ko.
84 If unsure, choose Y.
70 85
71config QETH_IPV6 86config QETH_IPV6
72 bool "IPv6 support for gigabit ethernet" 87 bool
73 depends on (QETH = IPV6) || (QETH && IPV6 = 'y') 88 depends on (QETH_L3 = IPV6) || (QETH_L3 && IPV6 = 'y')
74 help 89 default y
75 If CONFIG_QETH is switched on, this option will include IPv6
76 support in the qeth device driver.
77
78config QETH_VLAN
79 bool "VLAN support for gigabit ethernet"
80 depends on (QETH = VLAN_8021Q) || (QETH && VLAN_8021Q = 'y')
81 help
82 If CONFIG_QETH is switched on, this option will include IEEE
83 802.1q VLAN support in the qeth device driver.
84 90
85config CCWGROUP 91config CCWGROUP
86 tristate 92 tristate
87 default (LCS || CTC || QETH) 93 default (LCS || CTCM || QETH)
88 94
89endmenu 95endmenu
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index bbe3ab2e93d9..6382c04d2bdf 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -2,13 +2,15 @@
2# S/390 network devices 2# S/390 network devices
3# 3#
4 4
5ctc-objs := ctcmain.o ctcdbug.o 5ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o
6 6obj-$(CONFIG_CTCM) += ctcm.o fsm.o cu3088.o
7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
9obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
10obj-$(CONFIG_LCS) += lcs.o cu3088.o 9obj-$(CONFIG_LCS) += lcs.o cu3088.o
11obj-$(CONFIG_CLAW) += claw.o cu3088.o 10obj-$(CONFIG_CLAW) += claw.o cu3088.o
12qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o 11qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o qeth_core_offl.o
13qeth-$(CONFIG_PROC_FS) += qeth_proc.o
14obj-$(CONFIG_QETH) += qeth.o 12obj-$(CONFIG_QETH) += qeth.o
13qeth_l2-y += qeth_l2_main.o
14obj-$(CONFIG_QETH_L2) += qeth_l2.o
15qeth_l3-y += qeth_l3_main.o qeth_l3_sys.o
16obj-$(CONFIG_QETH_L3) += qeth_l3.o
diff --git a/drivers/s390/net/ctcdbug.c b/drivers/s390/net/ctcdbug.c
deleted file mode 100644
index e6e72deb36b5..000000000000
--- a/drivers/s390/net/ctcdbug.c
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 *
3 * linux/drivers/s390/net/ctcdbug.c
4 *
5 * CTC / ESCON network driver - s390 dbf exploit.
6 *
7 * Copyright 2000,2003 IBM Corporation
8 *
9 * Author(s): Original Code written by
10 * Peter Tiedemann (ptiedem@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include "ctcdbug.h"
28
29/**
30 * Debug Facility Stuff
31 */
32debug_info_t *ctc_dbf_setup = NULL;
33debug_info_t *ctc_dbf_data = NULL;
34debug_info_t *ctc_dbf_trace = NULL;
35
36DEFINE_PER_CPU(char[256], ctc_dbf_txt_buf);
37
38void
39ctc_unregister_dbf_views(void)
40{
41 if (ctc_dbf_setup)
42 debug_unregister(ctc_dbf_setup);
43 if (ctc_dbf_data)
44 debug_unregister(ctc_dbf_data);
45 if (ctc_dbf_trace)
46 debug_unregister(ctc_dbf_trace);
47}
48int
49ctc_register_dbf_views(void)
50{
51 ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME,
52 CTC_DBF_SETUP_PAGES,
53 CTC_DBF_SETUP_NR_AREAS,
54 CTC_DBF_SETUP_LEN);
55 ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME,
56 CTC_DBF_DATA_PAGES,
57 CTC_DBF_DATA_NR_AREAS,
58 CTC_DBF_DATA_LEN);
59 ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME,
60 CTC_DBF_TRACE_PAGES,
61 CTC_DBF_TRACE_NR_AREAS,
62 CTC_DBF_TRACE_LEN);
63
64 if ((ctc_dbf_setup == NULL) || (ctc_dbf_data == NULL) ||
65 (ctc_dbf_trace == NULL)) {
66 ctc_unregister_dbf_views();
67 return -ENOMEM;
68 }
69 debug_register_view(ctc_dbf_setup, &debug_hex_ascii_view);
70 debug_set_level(ctc_dbf_setup, CTC_DBF_SETUP_LEVEL);
71
72 debug_register_view(ctc_dbf_data, &debug_hex_ascii_view);
73 debug_set_level(ctc_dbf_data, CTC_DBF_DATA_LEVEL);
74
75 debug_register_view(ctc_dbf_trace, &debug_hex_ascii_view);
76 debug_set_level(ctc_dbf_trace, CTC_DBF_TRACE_LEVEL);
77
78 return 0;
79}
80
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h
deleted file mode 100644
index 413925ee23d1..000000000000
--- a/drivers/s390/net/ctcdbug.h
+++ /dev/null
@@ -1,125 +0,0 @@
1/*
2 *
3 * linux/drivers/s390/net/ctcdbug.h
4 *
5 * CTC / ESCON network driver - s390 dbf exploit.
6 *
7 * Copyright 2000,2003 IBM Corporation
8 *
9 * Author(s): Original Code written by
10 * Peter Tiedemann (ptiedem@de.ibm.com)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26#ifndef _CTCDBUG_H_
27#define _CTCDBUG_H_
28
29#include <asm/debug.h>
30#include "ctcmain.h"
31/**
32 * Debug Facility stuff
33 */
34#define CTC_DBF_SETUP_NAME "ctc_setup"
35#define CTC_DBF_SETUP_LEN 16
36#define CTC_DBF_SETUP_PAGES 8
37#define CTC_DBF_SETUP_NR_AREAS 1
38#define CTC_DBF_SETUP_LEVEL 3
39
40#define CTC_DBF_DATA_NAME "ctc_data"
41#define CTC_DBF_DATA_LEN 128
42#define CTC_DBF_DATA_PAGES 8
43#define CTC_DBF_DATA_NR_AREAS 1
44#define CTC_DBF_DATA_LEVEL 3
45
46#define CTC_DBF_TRACE_NAME "ctc_trace"
47#define CTC_DBF_TRACE_LEN 16
48#define CTC_DBF_TRACE_PAGES 4
49#define CTC_DBF_TRACE_NR_AREAS 2
50#define CTC_DBF_TRACE_LEVEL 3
51
52#define DBF_TEXT(name,level,text) \
53 do { \
54 debug_text_event(ctc_dbf_##name,level,text); \
55 } while (0)
56
57#define DBF_HEX(name,level,addr,len) \
58 do { \
59 debug_event(ctc_dbf_##name,level,(void*)(addr),len); \
60 } while (0)
61
62DECLARE_PER_CPU(char[256], ctc_dbf_txt_buf);
63extern debug_info_t *ctc_dbf_setup;
64extern debug_info_t *ctc_dbf_data;
65extern debug_info_t *ctc_dbf_trace;
66
67
68#define DBF_TEXT_(name,level,text...) \
69 do { \
70 char* ctc_dbf_txt_buf = get_cpu_var(ctc_dbf_txt_buf); \
71 sprintf(ctc_dbf_txt_buf, text); \
72 debug_text_event(ctc_dbf_##name,level,ctc_dbf_txt_buf); \
73 put_cpu_var(ctc_dbf_txt_buf); \
74 } while (0)
75
76#define DBF_SPRINTF(name,level,text...) \
77 do { \
78 debug_sprintf_event(ctc_dbf_trace, level, ##text ); \
79 debug_sprintf_event(ctc_dbf_trace, level, text ); \
80 } while (0)
81
82
83int ctc_register_dbf_views(void);
84
85void ctc_unregister_dbf_views(void);
86
87/**
88 * some more debug stuff
89 */
90
91#define HEXDUMP16(importance,header,ptr) \
92PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
93 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
94 *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
95 *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
96 *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
97 *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
98 *(((char*)ptr)+12),*(((char*)ptr)+13), \
99 *(((char*)ptr)+14),*(((char*)ptr)+15)); \
100PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
101 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
102 *(((char*)ptr)+16),*(((char*)ptr)+17), \
103 *(((char*)ptr)+18),*(((char*)ptr)+19), \
104 *(((char*)ptr)+20),*(((char*)ptr)+21), \
105 *(((char*)ptr)+22),*(((char*)ptr)+23), \
106 *(((char*)ptr)+24),*(((char*)ptr)+25), \
107 *(((char*)ptr)+26),*(((char*)ptr)+27), \
108 *(((char*)ptr)+28),*(((char*)ptr)+29), \
109 *(((char*)ptr)+30),*(((char*)ptr)+31));
110
111static inline void
112hex_dump(unsigned char *buf, size_t len)
113{
114 size_t i;
115
116 for (i = 0; i < len; i++) {
117 if (i && !(i % 16))
118 printk("\n");
119 printk("%02x ", *(buf + i));
120 }
121 printk("\n");
122}
123
124
125#endif
diff --git a/drivers/s390/net/ctcm_dbug.c b/drivers/s390/net/ctcm_dbug.c
new file mode 100644
index 000000000000..8eb25d00b2e7
--- /dev/null
+++ b/drivers/s390/net/ctcm_dbug.c
@@ -0,0 +1,67 @@
1/*
2 * drivers/s390/net/ctcm_dbug.c
3 *
4 * Copyright IBM Corp. 2001, 2007
5 * Authors: Peter Tiedemann (ptiedem@de.ibm.com)
6 *
7 */
8
9#include <linux/stddef.h>
10#include <linux/kernel.h>
11#include <linux/errno.h>
12#include <linux/slab.h>
13#include <linux/ctype.h>
14#include <linux/sysctl.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/fs.h>
18#include <linux/debugfs.h>
19#include "ctcm_dbug.h"
20
21/*
22 * Debug Facility Stuff
23 */
24
25DEFINE_PER_CPU(char[256], ctcm_dbf_txt_buf);
26
27struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS] = {
28 [CTCM_DBF_SETUP] = {"ctc_setup", 8, 1, 64, 5, NULL},
29 [CTCM_DBF_ERROR] = {"ctc_error", 8, 1, 64, 3, NULL},
30 [CTCM_DBF_TRACE] = {"ctc_trace", 8, 1, 64, 3, NULL},
31 [CTCM_DBF_MPC_SETUP] = {"mpc_setup", 8, 1, 64, 5, NULL},
32 [CTCM_DBF_MPC_ERROR] = {"mpc_error", 8, 1, 64, 3, NULL},
33 [CTCM_DBF_MPC_TRACE] = {"mpc_trace", 8, 1, 64, 3, NULL},
34};
35
36void ctcm_unregister_dbf_views(void)
37{
38 int x;
39 for (x = 0; x < CTCM_DBF_INFOS; x++) {
40 debug_unregister(ctcm_dbf[x].id);
41 ctcm_dbf[x].id = NULL;
42 }
43}
44
45int ctcm_register_dbf_views(void)
46{
47 int x;
48 for (x = 0; x < CTCM_DBF_INFOS; x++) {
49 /* register the areas */
50 ctcm_dbf[x].id = debug_register(ctcm_dbf[x].name,
51 ctcm_dbf[x].pages,
52 ctcm_dbf[x].areas,
53 ctcm_dbf[x].len);
54 if (ctcm_dbf[x].id == NULL) {
55 ctcm_unregister_dbf_views();
56 return -ENOMEM;
57 }
58
59 /* register a view */
60 debug_register_view(ctcm_dbf[x].id, &debug_hex_ascii_view);
61 /* set a passing level */
62 debug_set_level(ctcm_dbf[x].id, ctcm_dbf[x].level);
63 }
64
65 return 0;
66}
67
diff --git a/drivers/s390/net/ctcm_dbug.h b/drivers/s390/net/ctcm_dbug.h
new file mode 100644
index 000000000000..fdff34fe59a2
--- /dev/null
+++ b/drivers/s390/net/ctcm_dbug.h
@@ -0,0 +1,158 @@
1/*
2 * drivers/s390/net/ctcm_dbug.h
3 *
4 * Copyright IBM Corp. 2001, 2007
5 * Authors: Peter Tiedemann (ptiedem@de.ibm.com)
6 *
7 */
8
9#ifndef _CTCM_DBUG_H_
10#define _CTCM_DBUG_H_
11
12/*
13 * Debug Facility stuff
14 */
15
16#include <asm/debug.h>
17
18#ifdef DEBUG
19 #define do_debug 1
20#else
21 #define do_debug 0
22#endif
23#ifdef DEBUGDATA
24 #define do_debug_data 1
25#else
26 #define do_debug_data 0
27#endif
28#ifdef DEBUGCCW
29 #define do_debug_ccw 1
30#else
31 #define do_debug_ccw 0
32#endif
33
34/* define dbf debug levels similar to kernel msg levels */
35#define CTC_DBF_ALWAYS 0 /* always print this */
36#define CTC_DBF_EMERG 0 /* system is unusable */
37#define CTC_DBF_ALERT 1 /* action must be taken immediately */
38#define CTC_DBF_CRIT 2 /* critical conditions */
39#define CTC_DBF_ERROR 3 /* error conditions */
40#define CTC_DBF_WARN 4 /* warning conditions */
41#define CTC_DBF_NOTICE 5 /* normal but significant condition */
42#define CTC_DBF_INFO 5 /* informational */
43#define CTC_DBF_DEBUG 6 /* debug-level messages */
44
45DECLARE_PER_CPU(char[256], ctcm_dbf_txt_buf);
46
47enum ctcm_dbf_names {
48 CTCM_DBF_SETUP,
49 CTCM_DBF_ERROR,
50 CTCM_DBF_TRACE,
51 CTCM_DBF_MPC_SETUP,
52 CTCM_DBF_MPC_ERROR,
53 CTCM_DBF_MPC_TRACE,
54 CTCM_DBF_INFOS /* must be last element */
55};
56
57struct ctcm_dbf_info {
58 char name[DEBUG_MAX_NAME_LEN];
59 int pages;
60 int areas;
61 int len;
62 int level;
63 debug_info_t *id;
64};
65
66extern struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS];
67
68int ctcm_register_dbf_views(void);
69void ctcm_unregister_dbf_views(void);
70
71static inline const char *strtail(const char *s, int n)
72{
73 int l = strlen(s);
74 return (l > n) ? s + (l - n) : s;
75}
76
77/* sort out levels early to avoid unnecessary sprintfs */
78static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
79{
80 return (dbf_grp->level >= level);
81}
82
83#define CTCM_FUNTAIL strtail((char *)__func__, 16)
84
85#define CTCM_DBF_TEXT(name, level, text) \
86 do { \
87 debug_text_event(ctcm_dbf[CTCM_DBF_##name].id, level, text); \
88 } while (0)
89
90#define CTCM_DBF_HEX(name, level, addr, len) \
91 do { \
92 debug_event(ctcm_dbf[CTCM_DBF_##name].id, \
93 level, (void *)(addr), len); \
94 } while (0)
95
96#define CTCM_DBF_TEXT_(name, level, text...) \
97 do { \
98 if (ctcm_dbf_passes(ctcm_dbf[CTCM_DBF_##name].id, level)) { \
99 char *ctcm_dbf_txt_buf = \
100 get_cpu_var(ctcm_dbf_txt_buf); \
101 sprintf(ctcm_dbf_txt_buf, text); \
102 debug_text_event(ctcm_dbf[CTCM_DBF_##name].id, \
103 level, ctcm_dbf_txt_buf); \
104 put_cpu_var(ctcm_dbf_txt_buf); \
105 } \
106 } while (0)
107
108/*
109 * cat : one of {setup, mpc_setup, trace, mpc_trace, error, mpc_error}.
110 * dev : netdevice with valid name field.
111 * text: any text string.
112 */
113#define CTCM_DBF_DEV_NAME(cat, dev, text) \
114 do { \
115 CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%s) : %s", \
116 CTCM_FUNTAIL, dev->name, text); \
117 } while (0)
118
119#define MPC_DBF_DEV_NAME(cat, dev, text) \
120 do { \
121 CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%s) : %s", \
122 CTCM_FUNTAIL, dev->name, text); \
123 } while (0)
124
125#define CTCMY_DBF_DEV_NAME(cat, dev, text) \
126 do { \
127 if (IS_MPCDEV(dev)) \
128 MPC_DBF_DEV_NAME(cat, dev, text); \
129 else \
130 CTCM_DBF_DEV_NAME(cat, dev, text); \
131 } while (0)
132
133/*
134 * cat : one of {setup, mpc_setup, trace, mpc_trace, error, mpc_error}.
135 * dev : netdevice.
136 * text: any text string.
137 */
138#define CTCM_DBF_DEV(cat, dev, text) \
139 do { \
140 CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%p) : %s", \
141 CTCM_FUNTAIL, dev, text); \
142 } while (0)
143
144#define MPC_DBF_DEV(cat, dev, text) \
145 do { \
146 CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%p) : %s", \
147 CTCM_FUNTAIL, dev, text); \
148 } while (0)
149
150#define CTCMY_DBF_DEV(cat, dev, text) \
151 do { \
152 if (IS_MPCDEV(dev)) \
153 MPC_DBF_DEV(cat, dev, text); \
154 else \
155 CTCM_DBF_DEV(cat, dev, text); \
156 } while (0)
157
158#endif
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c
new file mode 100644
index 000000000000..2a106f3a076d
--- /dev/null
+++ b/drivers/s390/net/ctcm_fsms.c
@@ -0,0 +1,2347 @@
1/*
2 * drivers/s390/net/ctcm_fsms.c
3 *
4 * Copyright IBM Corp. 2001, 2007
5 * Authors: Fritz Elfert (felfert@millenux.com)
6 * Peter Tiedemann (ptiedem@de.ibm.com)
7 * MPC additions :
8 * Belinda Thompson (belindat@us.ibm.com)
9 * Andy Richter (richtera@us.ibm.com)
10 */
11
12#undef DEBUG
13#undef DEBUGDATA
14#undef DEBUGCCW
15
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/slab.h>
20#include <linux/errno.h>
21#include <linux/types.h>
22#include <linux/interrupt.h>
23#include <linux/timer.h>
24#include <linux/bitops.h>
25
26#include <linux/signal.h>
27#include <linux/string.h>
28
29#include <linux/ip.h>
30#include <linux/if_arp.h>
31#include <linux/tcp.h>
32#include <linux/skbuff.h>
33#include <linux/ctype.h>
34#include <net/dst.h>
35
36#include <linux/io.h>
37#include <asm/ccwdev.h>
38#include <asm/ccwgroup.h>
39#include <linux/uaccess.h>
40
41#include <asm/idals.h>
42
43#include "fsm.h"
44#include "cu3088.h"
45
46#include "ctcm_dbug.h"
47#include "ctcm_main.h"
48#include "ctcm_fsms.h"
49
50const char *dev_state_names[] = {
51 [DEV_STATE_STOPPED] = "Stopped",
52 [DEV_STATE_STARTWAIT_RXTX] = "StartWait RXTX",
53 [DEV_STATE_STARTWAIT_RX] = "StartWait RX",
54 [DEV_STATE_STARTWAIT_TX] = "StartWait TX",
55 [DEV_STATE_STOPWAIT_RXTX] = "StopWait RXTX",
56 [DEV_STATE_STOPWAIT_RX] = "StopWait RX",
57 [DEV_STATE_STOPWAIT_TX] = "StopWait TX",
58 [DEV_STATE_RUNNING] = "Running",
59};
60
61const char *dev_event_names[] = {
62 [DEV_EVENT_START] = "Start",
63 [DEV_EVENT_STOP] = "Stop",
64 [DEV_EVENT_RXUP] = "RX up",
65 [DEV_EVENT_TXUP] = "TX up",
66 [DEV_EVENT_RXDOWN] = "RX down",
67 [DEV_EVENT_TXDOWN] = "TX down",
68 [DEV_EVENT_RESTART] = "Restart",
69};
70
71const char *ctc_ch_event_names[] = {
72 [CTC_EVENT_IO_SUCCESS] = "ccw_device success",
73 [CTC_EVENT_IO_EBUSY] = "ccw_device busy",
74 [CTC_EVENT_IO_ENODEV] = "ccw_device enodev",
75 [CTC_EVENT_IO_UNKNOWN] = "ccw_device unknown",
76 [CTC_EVENT_ATTNBUSY] = "Status ATTN & BUSY",
77 [CTC_EVENT_ATTN] = "Status ATTN",
78 [CTC_EVENT_BUSY] = "Status BUSY",
79 [CTC_EVENT_UC_RCRESET] = "Unit check remote reset",
80 [CTC_EVENT_UC_RSRESET] = "Unit check remote system reset",
81 [CTC_EVENT_UC_TXTIMEOUT] = "Unit check TX timeout",
82 [CTC_EVENT_UC_TXPARITY] = "Unit check TX parity",
83 [CTC_EVENT_UC_HWFAIL] = "Unit check Hardware failure",
84 [CTC_EVENT_UC_RXPARITY] = "Unit check RX parity",
85 [CTC_EVENT_UC_ZERO] = "Unit check ZERO",
86 [CTC_EVENT_UC_UNKNOWN] = "Unit check Unknown",
87 [CTC_EVENT_SC_UNKNOWN] = "SubChannel check Unknown",
88 [CTC_EVENT_MC_FAIL] = "Machine check failure",
89 [CTC_EVENT_MC_GOOD] = "Machine check operational",
90 [CTC_EVENT_IRQ] = "IRQ normal",
91 [CTC_EVENT_FINSTAT] = "IRQ final",
92 [CTC_EVENT_TIMER] = "Timer",
93 [CTC_EVENT_START] = "Start",
94 [CTC_EVENT_STOP] = "Stop",
95 /*
96 * additional MPC events
97 */
98 [CTC_EVENT_SEND_XID] = "XID Exchange",
99 [CTC_EVENT_RSWEEP_TIMER] = "MPC Group Sweep Timer",
100};
101
102const char *ctc_ch_state_names[] = {
103 [CTC_STATE_IDLE] = "Idle",
104 [CTC_STATE_STOPPED] = "Stopped",
105 [CTC_STATE_STARTWAIT] = "StartWait",
106 [CTC_STATE_STARTRETRY] = "StartRetry",
107 [CTC_STATE_SETUPWAIT] = "SetupWait",
108 [CTC_STATE_RXINIT] = "RX init",
109 [CTC_STATE_TXINIT] = "TX init",
110 [CTC_STATE_RX] = "RX",
111 [CTC_STATE_TX] = "TX",
112 [CTC_STATE_RXIDLE] = "RX idle",
113 [CTC_STATE_TXIDLE] = "TX idle",
114 [CTC_STATE_RXERR] = "RX error",
115 [CTC_STATE_TXERR] = "TX error",
116 [CTC_STATE_TERM] = "Terminating",
117 [CTC_STATE_DTERM] = "Restarting",
118 [CTC_STATE_NOTOP] = "Not operational",
119 /*
120 * additional MPC states
121 */
122 [CH_XID0_PENDING] = "Pending XID0 Start",
123 [CH_XID0_INPROGRESS] = "In XID0 Negotiations ",
124 [CH_XID7_PENDING] = "Pending XID7 P1 Start",
125 [CH_XID7_PENDING1] = "Active XID7 P1 Exchange ",
126 [CH_XID7_PENDING2] = "Pending XID7 P2 Start ",
127 [CH_XID7_PENDING3] = "Active XID7 P2 Exchange ",
128 [CH_XID7_PENDING4] = "XID7 Complete - Pending READY ",
129};
130
131static void ctcm_action_nop(fsm_instance *fi, int event, void *arg);
132
133/*
134 * ----- static ctcm actions for channel statemachine -----
135 *
136*/
137static void chx_txdone(fsm_instance *fi, int event, void *arg);
138static void chx_rx(fsm_instance *fi, int event, void *arg);
139static void chx_rxidle(fsm_instance *fi, int event, void *arg);
140static void chx_firstio(fsm_instance *fi, int event, void *arg);
141static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg);
142static void ctcm_chx_start(fsm_instance *fi, int event, void *arg);
143static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg);
144static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg);
145static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg);
146static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg);
147static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg);
148static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg);
149static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg);
150static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg);
151static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg);
152static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg);
153static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg);
154static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg);
155
156/*
157 * ----- static ctcmpc actions for ctcmpc channel statemachine -----
158 *
159*/
160static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg);
161static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg);
162static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg);
163/* shared :
164static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg);
165static void ctcm_chx_start(fsm_instance *fi, int event, void *arg);
166static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg);
167static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg);
168static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg);
169static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg);
170static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg);
171static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg);
172static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg);
173static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg);
174static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg);
175static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg);
176static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg);
177static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg);
178*/
179static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg);
180static void ctcmpc_chx_attnbusy(fsm_instance *, int, void *);
181static void ctcmpc_chx_resend(fsm_instance *, int, void *);
182static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg);
183
184/**
185 * Check return code of a preceeding ccw_device call, halt_IO etc...
186 *
187 * ch : The channel, the error belongs to.
188 * Returns the error code (!= 0) to inspect.
189 */
190void ctcm_ccw_check_rc(struct channel *ch, int rc, char *msg)
191{
192 CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
193 "ccw error %s (%s): %04x\n", ch->id, msg, rc);
194 switch (rc) {
195 case -EBUSY:
196 ctcm_pr_warn("%s (%s): Busy !\n", ch->id, msg);
197 fsm_event(ch->fsm, CTC_EVENT_IO_EBUSY, ch);
198 break;
199 case -ENODEV:
200 ctcm_pr_emerg("%s (%s): Invalid device called for IO\n",
201 ch->id, msg);
202 fsm_event(ch->fsm, CTC_EVENT_IO_ENODEV, ch);
203 break;
204 default:
205 ctcm_pr_emerg("%s (%s): Unknown error in do_IO %04x\n",
206 ch->id, msg, rc);
207 fsm_event(ch->fsm, CTC_EVENT_IO_UNKNOWN, ch);
208 }
209}
210
211void ctcm_purge_skb_queue(struct sk_buff_head *q)
212{
213 struct sk_buff *skb;
214
215 CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
216
217 while ((skb = skb_dequeue(q))) {
218 atomic_dec(&skb->users);
219 dev_kfree_skb_any(skb);
220 }
221}
222
223/**
224 * NOP action for statemachines
225 */
226static void ctcm_action_nop(fsm_instance *fi, int event, void *arg)
227{
228}
229
230/*
231 * Actions for channel - statemachines.
232 */
233
234/**
235 * Normal data has been send. Free the corresponding
236 * skb (it's in io_queue), reset dev->tbusy and
237 * revert to idle state.
238 *
239 * fi An instance of a channel statemachine.
240 * event The event, just happened.
241 * arg Generic pointer, casted from channel * upon call.
242 */
243static void chx_txdone(fsm_instance *fi, int event, void *arg)
244{
245 struct channel *ch = arg;
246 struct net_device *dev = ch->netdev;
247 struct ctcm_priv *priv = dev->priv;
248 struct sk_buff *skb;
249 int first = 1;
250 int i;
251 unsigned long duration;
252 struct timespec done_stamp = current_kernel_time(); /* xtime */
253
254 duration =
255 (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
256 (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
257 if (duration > ch->prof.tx_time)
258 ch->prof.tx_time = duration;
259
260 if (ch->irb->scsw.count != 0)
261 ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n",
262 dev->name, ch->irb->scsw.count);
263 fsm_deltimer(&ch->timer);
264 while ((skb = skb_dequeue(&ch->io_queue))) {
265 priv->stats.tx_packets++;
266 priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
267 if (first) {
268 priv->stats.tx_bytes += 2;
269 first = 0;
270 }
271 atomic_dec(&skb->users);
272 dev_kfree_skb_irq(skb);
273 }
274 spin_lock(&ch->collect_lock);
275 clear_normalized_cda(&ch->ccw[4]);
276 if (ch->collect_len > 0) {
277 int rc;
278
279 if (ctcm_checkalloc_buffer(ch)) {
280 spin_unlock(&ch->collect_lock);
281 return;
282 }
283 ch->trans_skb->data = ch->trans_skb_data;
284 skb_reset_tail_pointer(ch->trans_skb);
285 ch->trans_skb->len = 0;
286 if (ch->prof.maxmulti < (ch->collect_len + 2))
287 ch->prof.maxmulti = ch->collect_len + 2;
288 if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))
289 ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);
290 *((__u16 *)skb_put(ch->trans_skb, 2)) = ch->collect_len + 2;
291 i = 0;
292 while ((skb = skb_dequeue(&ch->collect_queue))) {
293 skb_copy_from_linear_data(skb,
294 skb_put(ch->trans_skb, skb->len), skb->len);
295 priv->stats.tx_packets++;
296 priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
297 atomic_dec(&skb->users);
298 dev_kfree_skb_irq(skb);
299 i++;
300 }
301 ch->collect_len = 0;
302 spin_unlock(&ch->collect_lock);
303 ch->ccw[1].count = ch->trans_skb->len;
304 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
305 ch->prof.send_stamp = current_kernel_time(); /* xtime */
306 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
307 (unsigned long)ch, 0xff, 0);
308 ch->prof.doios_multi++;
309 if (rc != 0) {
310 priv->stats.tx_dropped += i;
311 priv->stats.tx_errors += i;
312 fsm_deltimer(&ch->timer);
313 ctcm_ccw_check_rc(ch, rc, "chained TX");
314 }
315 } else {
316 spin_unlock(&ch->collect_lock);
317 fsm_newstate(fi, CTC_STATE_TXIDLE);
318 }
319 ctcm_clear_busy_do(dev);
320}
321
322/**
323 * Initial data is sent.
324 * Notify device statemachine that we are up and
325 * running.
326 *
327 * fi An instance of a channel statemachine.
328 * event The event, just happened.
329 * arg Generic pointer, casted from channel * upon call.
330 */
331void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg)
332{
333 struct channel *ch = arg;
334 struct net_device *dev = ch->netdev;
335 struct ctcm_priv *priv = dev->priv;
336
337 CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
338 fsm_deltimer(&ch->timer);
339 fsm_newstate(fi, CTC_STATE_TXIDLE);
340 fsm_event(priv->fsm, DEV_EVENT_TXUP, ch->netdev);
341}
342
343/**
344 * Got normal data, check for sanity, queue it up, allocate new buffer
345 * trigger bottom half, and initiate next read.
346 *
347 * fi An instance of a channel statemachine.
348 * event The event, just happened.
349 * arg Generic pointer, casted from channel * upon call.
350 */
351static void chx_rx(fsm_instance *fi, int event, void *arg)
352{
353 struct channel *ch = arg;
354 struct net_device *dev = ch->netdev;
355 struct ctcm_priv *priv = dev->priv;
356 int len = ch->max_bufsize - ch->irb->scsw.count;
357 struct sk_buff *skb = ch->trans_skb;
358 __u16 block_len = *((__u16 *)skb->data);
359 int check_len;
360 int rc;
361
362 fsm_deltimer(&ch->timer);
363 if (len < 8) {
364 ctcm_pr_debug("%s: got packet with length %d < 8\n",
365 dev->name, len);
366 priv->stats.rx_dropped++;
367 priv->stats.rx_length_errors++;
368 goto again;
369 }
370 if (len > ch->max_bufsize) {
371 ctcm_pr_debug("%s: got packet with length %d > %d\n",
372 dev->name, len, ch->max_bufsize);
373 priv->stats.rx_dropped++;
374 priv->stats.rx_length_errors++;
375 goto again;
376 }
377
378 /*
379 * VM TCP seems to have a bug sending 2 trailing bytes of garbage.
380 */
381 switch (ch->protocol) {
382 case CTCM_PROTO_S390:
383 case CTCM_PROTO_OS390:
384 check_len = block_len + 2;
385 break;
386 default:
387 check_len = block_len;
388 break;
389 }
390 if ((len < block_len) || (len > check_len)) {
391 ctcm_pr_debug("%s: got block length %d != rx length %d\n",
392 dev->name, block_len, len);
393 if (do_debug)
394 ctcmpc_dump_skb(skb, 0);
395
396 *((__u16 *)skb->data) = len;
397 priv->stats.rx_dropped++;
398 priv->stats.rx_length_errors++;
399 goto again;
400 }
401 block_len -= 2;
402 if (block_len > 0) {
403 *((__u16 *)skb->data) = block_len;
404 ctcm_unpack_skb(ch, skb);
405 }
406 again:
407 skb->data = ch->trans_skb_data;
408 skb_reset_tail_pointer(skb);
409 skb->len = 0;
410 if (ctcm_checkalloc_buffer(ch))
411 return;
412 ch->ccw[1].count = ch->max_bufsize;
413 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
414 (unsigned long)ch, 0xff, 0);
415 if (rc != 0)
416 ctcm_ccw_check_rc(ch, rc, "normal RX");
417}
418
419/**
420 * Initialize connection by sending a __u16 of value 0.
421 *
422 * fi An instance of a channel statemachine.
423 * event The event, just happened.
424 * arg Generic pointer, casted from channel * upon call.
425 */
426static void chx_firstio(fsm_instance *fi, int event, void *arg)
427{
428 struct channel *ch = arg;
429 int rc;
430
431 CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
432
433 if (fsm_getstate(fi) == CTC_STATE_TXIDLE)
434 ctcm_pr_debug("%s: remote side issued READ?, init.\n", ch->id);
435 fsm_deltimer(&ch->timer);
436 if (ctcm_checkalloc_buffer(ch))
437 return;
438 if ((fsm_getstate(fi) == CTC_STATE_SETUPWAIT) &&
439 (ch->protocol == CTCM_PROTO_OS390)) {
440 /* OS/390 resp. z/OS */
441 if (CHANNEL_DIRECTION(ch->flags) == READ) {
442 *((__u16 *)ch->trans_skb->data) = CTCM_INITIAL_BLOCKLEN;
443 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC,
444 CTC_EVENT_TIMER, ch);
445 chx_rxidle(fi, event, arg);
446 } else {
447 struct net_device *dev = ch->netdev;
448 struct ctcm_priv *priv = dev->priv;
449 fsm_newstate(fi, CTC_STATE_TXIDLE);
450 fsm_event(priv->fsm, DEV_EVENT_TXUP, dev);
451 }
452 return;
453 }
454
455 /*
456 * Don't setup a timer for receiving the initial RX frame
457 * if in compatibility mode, since VM TCP delays the initial
458 * frame until it has some data to send.
459 */
460 if ((CHANNEL_DIRECTION(ch->flags) == WRITE) ||
461 (ch->protocol != CTCM_PROTO_S390))
462 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
463
464 *((__u16 *)ch->trans_skb->data) = CTCM_INITIAL_BLOCKLEN;
465 ch->ccw[1].count = 2; /* Transfer only length */
466
467 fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == READ)
468 ? CTC_STATE_RXINIT : CTC_STATE_TXINIT);
469 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
470 (unsigned long)ch, 0xff, 0);
471 if (rc != 0) {
472 fsm_deltimer(&ch->timer);
473 fsm_newstate(fi, CTC_STATE_SETUPWAIT);
474 ctcm_ccw_check_rc(ch, rc, "init IO");
475 }
476 /*
477 * If in compatibility mode since we don't setup a timer, we
478 * also signal RX channel up immediately. This enables us
479 * to send packets early which in turn usually triggers some
480 * reply from VM TCP which brings up the RX channel to it's
481 * final state.
482 */
483 if ((CHANNEL_DIRECTION(ch->flags) == READ) &&
484 (ch->protocol == CTCM_PROTO_S390)) {
485 struct net_device *dev = ch->netdev;
486 struct ctcm_priv *priv = dev->priv;
487 fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
488 }
489}
490
491/**
492 * Got initial data, check it. If OK,
493 * notify device statemachine that we are up and
494 * running.
495 *
496 * fi An instance of a channel statemachine.
497 * event The event, just happened.
498 * arg Generic pointer, casted from channel * upon call.
499 */
500static void chx_rxidle(fsm_instance *fi, int event, void *arg)
501{
502 struct channel *ch = arg;
503 struct net_device *dev = ch->netdev;
504 struct ctcm_priv *priv = dev->priv;
505 __u16 buflen;
506 int rc;
507
508 CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
509 fsm_deltimer(&ch->timer);
510 buflen = *((__u16 *)ch->trans_skb->data);
511 if (do_debug)
512 ctcm_pr_debug("%s: Initial RX count %d\n", dev->name, buflen);
513
514 if (buflen >= CTCM_INITIAL_BLOCKLEN) {
515 if (ctcm_checkalloc_buffer(ch))
516 return;
517 ch->ccw[1].count = ch->max_bufsize;
518 fsm_newstate(fi, CTC_STATE_RXIDLE);
519 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
520 (unsigned long)ch, 0xff, 0);
521 if (rc != 0) {
522 fsm_newstate(fi, CTC_STATE_RXINIT);
523 ctcm_ccw_check_rc(ch, rc, "initial RX");
524 } else
525 fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
526 } else {
527 if (do_debug)
528 ctcm_pr_debug("%s: Initial RX count %d not %d\n",
529 dev->name, buflen, CTCM_INITIAL_BLOCKLEN);
530 chx_firstio(fi, event, arg);
531 }
532}
533
534/**
535 * Set channel into extended mode.
536 *
537 * fi An instance of a channel statemachine.
538 * event The event, just happened.
539 * arg Generic pointer, casted from channel * upon call.
540 */
541static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)
542{
543 struct channel *ch = arg;
544 int rc;
545 unsigned long saveflags = 0;
546 int timeout = CTCM_TIME_5_SEC;
547
548 fsm_deltimer(&ch->timer);
549 if (IS_MPC(ch)) {
550 timeout = 1500;
551 if (do_debug)
552 ctcm_pr_debug("ctcm enter: %s(): cp=%i ch=0x%p id=%s\n",
553 __FUNCTION__, smp_processor_id(), ch, ch->id);
554 }
555 fsm_addtimer(&ch->timer, timeout, CTC_EVENT_TIMER, ch);
556 fsm_newstate(fi, CTC_STATE_SETUPWAIT);
557 if (do_debug_ccw && IS_MPC(ch))
558 ctcmpc_dumpit((char *)&ch->ccw[6], sizeof(struct ccw1) * 2);
559
560 if (event == CTC_EVENT_TIMER) /* only for timer not yet locked */
561 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
562 /* Such conditional locking is undeterministic in
563 * static view. => ignore sparse warnings here. */
564
565 rc = ccw_device_start(ch->cdev, &ch->ccw[6],
566 (unsigned long)ch, 0xff, 0);
567 if (event == CTC_EVENT_TIMER) /* see above comments */
568 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
569 if (rc != 0) {
570 fsm_deltimer(&ch->timer);
571 fsm_newstate(fi, CTC_STATE_STARTWAIT);
572 ctcm_ccw_check_rc(ch, rc, "set Mode");
573 } else
574 ch->retry = 0;
575}
576
577/**
578 * Setup channel.
579 *
580 * fi An instance of a channel statemachine.
581 * event The event, just happened.
582 * arg Generic pointer, casted from channel * upon call.
583 */
584static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)
585{
586 struct channel *ch = arg;
587 int rc;
588 struct net_device *dev;
589 unsigned long saveflags;
590
591 CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
592 if (ch == NULL) {
593 ctcm_pr_warn("chx_start ch=NULL\n");
594 return;
595 }
596 if (ch->netdev == NULL) {
597 ctcm_pr_warn("chx_start dev=NULL, id=%s\n", ch->id);
598 return;
599 }
600 dev = ch->netdev;
601
602 if (do_debug)
603 ctcm_pr_debug("%s: %s channel start\n", dev->name,
604 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
605
606 if (ch->trans_skb != NULL) {
607 clear_normalized_cda(&ch->ccw[1]);
608 dev_kfree_skb(ch->trans_skb);
609 ch->trans_skb = NULL;
610 }
611 if (CHANNEL_DIRECTION(ch->flags) == READ) {
612 ch->ccw[1].cmd_code = CCW_CMD_READ;
613 ch->ccw[1].flags = CCW_FLAG_SLI;
614 ch->ccw[1].count = 0;
615 } else {
616 ch->ccw[1].cmd_code = CCW_CMD_WRITE;
617 ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
618 ch->ccw[1].count = 0;
619 }
620 if (ctcm_checkalloc_buffer(ch)) {
621 ctcm_pr_notice("%s: %s trans_skb allocation delayed "
622 "until first transfer\n", dev->name,
623 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
624 }
625
626 ch->ccw[0].cmd_code = CCW_CMD_PREPARE;
627 ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
628 ch->ccw[0].count = 0;
629 ch->ccw[0].cda = 0;
630 ch->ccw[2].cmd_code = CCW_CMD_NOOP; /* jointed CE + DE */
631 ch->ccw[2].flags = CCW_FLAG_SLI;
632 ch->ccw[2].count = 0;
633 ch->ccw[2].cda = 0;
634 memcpy(&ch->ccw[3], &ch->ccw[0], sizeof(struct ccw1) * 3);
635 ch->ccw[4].cda = 0;
636 ch->ccw[4].flags &= ~CCW_FLAG_IDA;
637
638 fsm_newstate(fi, CTC_STATE_STARTWAIT);
639 fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch);
640 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
641 rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
642 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
643 if (rc != 0) {
644 if (rc != -EBUSY)
645 fsm_deltimer(&ch->timer);
646 ctcm_ccw_check_rc(ch, rc, "initial HaltIO");
647 }
648}
649
650/**
651 * Shutdown a channel.
652 *
653 * fi An instance of a channel statemachine.
654 * event The event, just happened.
655 * arg Generic pointer, casted from channel * upon call.
656 */
657static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)
658{
659 struct channel *ch = arg;
660 unsigned long saveflags = 0;
661 int rc;
662 int oldstate;
663
664 CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
665 fsm_deltimer(&ch->timer);
666 if (IS_MPC(ch))
667 fsm_deltimer(&ch->sweep_timer);
668
669 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
670
671 if (event == CTC_EVENT_STOP) /* only for STOP not yet locked */
672 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
673 /* Such conditional locking is undeterministic in
674 * static view. => ignore sparse warnings here. */
675 oldstate = fsm_getstate(fi);
676 fsm_newstate(fi, CTC_STATE_TERM);
677 rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
678
679 if (event == CTC_EVENT_STOP)
680 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
681 /* see remark above about conditional locking */
682
683 if (rc != 0 && rc != -EBUSY) {
684 fsm_deltimer(&ch->timer);
685 if (event != CTC_EVENT_STOP) {
686 fsm_newstate(fi, oldstate);
687 ctcm_ccw_check_rc(ch, rc, (char *)__FUNCTION__);
688 }
689 }
690}
691
692/**
693 * Cleanup helper for chx_fail and chx_stopped
694 * cleanup channels queue and notify interface statemachine.
695 *
696 * fi An instance of a channel statemachine.
697 * state The next state (depending on caller).
698 * ch The channel to operate on.
699 */
700static void ctcm_chx_cleanup(fsm_instance *fi, int state,
701 struct channel *ch)
702{
703 struct net_device *dev = ch->netdev;
704 struct ctcm_priv *priv = dev->priv;
705
706 CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
707
708 fsm_deltimer(&ch->timer);
709 if (IS_MPC(ch))
710 fsm_deltimer(&ch->sweep_timer);
711
712 fsm_newstate(fi, state);
713 if (state == CTC_STATE_STOPPED && ch->trans_skb != NULL) {
714 clear_normalized_cda(&ch->ccw[1]);
715 dev_kfree_skb_any(ch->trans_skb);
716 ch->trans_skb = NULL;
717 }
718
719 ch->th_seg = 0x00;
720 ch->th_seq_num = 0x00;
721 if (CHANNEL_DIRECTION(ch->flags) == READ) {
722 skb_queue_purge(&ch->io_queue);
723 fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
724 } else {
725 ctcm_purge_skb_queue(&ch->io_queue);
726 if (IS_MPC(ch))
727 ctcm_purge_skb_queue(&ch->sweep_queue);
728 spin_lock(&ch->collect_lock);
729 ctcm_purge_skb_queue(&ch->collect_queue);
730 ch->collect_len = 0;
731 spin_unlock(&ch->collect_lock);
732 fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
733 }
734}
735
736/**
737 * A channel has successfully been halted.
738 * Cleanup it's queue and notify interface statemachine.
739 *
740 * fi An instance of a channel statemachine.
741 * event The event, just happened.
742 * arg Generic pointer, casted from channel * upon call.
743 */
744static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg)
745{
746 CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
747 ctcm_chx_cleanup(fi, CTC_STATE_STOPPED, arg);
748}
749
750/**
751 * A stop command from device statemachine arrived and we are in
752 * not operational mode. Set state to stopped.
753 *
754 * fi An instance of a channel statemachine.
755 * event The event, just happened.
756 * arg Generic pointer, casted from channel * upon call.
757 */
758static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg)
759{
760 fsm_newstate(fi, CTC_STATE_STOPPED);
761}
762
763/**
764 * A machine check for no path, not operational status or gone device has
765 * happened.
766 * Cleanup queue and notify interface statemachine.
767 *
768 * fi An instance of a channel statemachine.
769 * event The event, just happened.
770 * arg Generic pointer, casted from channel * upon call.
771 */
772static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg)
773{
774 CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
775 ctcm_chx_cleanup(fi, CTC_STATE_NOTOP, arg);
776}
777
778/**
779 * Handle error during setup of channel.
780 *
781 * fi An instance of a channel statemachine.
782 * event The event, just happened.
783 * arg Generic pointer, casted from channel * upon call.
784 */
785static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg)
786{
787 struct channel *ch = arg;
788 struct net_device *dev = ch->netdev;
789 struct ctcm_priv *priv = dev->priv;
790
791 /*
792 * Special case: Got UC_RCRESET on setmode.
793 * This means that remote side isn't setup. In this case
794 * simply retry after some 10 secs...
795 */
796 if ((fsm_getstate(fi) == CTC_STATE_SETUPWAIT) &&
797 ((event == CTC_EVENT_UC_RCRESET) ||
798 (event == CTC_EVENT_UC_RSRESET))) {
799 fsm_newstate(fi, CTC_STATE_STARTRETRY);
800 fsm_deltimer(&ch->timer);
801 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
802 if (!IS_MPC(ch) && (CHANNEL_DIRECTION(ch->flags) == READ)) {
803 int rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
804 if (rc != 0)
805 ctcm_ccw_check_rc(ch, rc,
806 "HaltIO in chx_setuperr");
807 }
808 return;
809 }
810
811 CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,
812 "%s : %s error during %s channel setup state=%s\n",
813 dev->name, ctc_ch_event_names[event],
814 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX",
815 fsm_getstate_str(fi));
816
817 if (CHANNEL_DIRECTION(ch->flags) == READ) {
818 fsm_newstate(fi, CTC_STATE_RXERR);
819 fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
820 } else {
821 fsm_newstate(fi, CTC_STATE_TXERR);
822 fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
823 }
824}
825
826/**
827 * Restart a channel after an error.
828 *
829 * fi An instance of a channel statemachine.
830 * event The event, just happened.
831 * arg Generic pointer, casted from channel * upon call.
832 */
833static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg)
834{
835 struct channel *ch = arg;
836 struct net_device *dev = ch->netdev;
837 unsigned long saveflags = 0;
838 int oldstate;
839 int rc;
840
841 CTCM_DBF_TEXT(TRACE, CTC_DBF_NOTICE, __FUNCTION__);
842 fsm_deltimer(&ch->timer);
843 ctcm_pr_debug("%s: %s channel restart\n", dev->name,
844 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
845 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
846 oldstate = fsm_getstate(fi);
847 fsm_newstate(fi, CTC_STATE_STARTWAIT);
848 if (event == CTC_EVENT_TIMER) /* only for timer not yet locked */
849 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
850 /* Such conditional locking is a known problem for
851 * sparse because its undeterministic in static view.
852 * Warnings should be ignored here. */
853 rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
854 if (event == CTC_EVENT_TIMER)
855 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
856 if (rc != 0) {
857 if (rc != -EBUSY) {
858 fsm_deltimer(&ch->timer);
859 fsm_newstate(fi, oldstate);
860 }
861 ctcm_ccw_check_rc(ch, rc, "HaltIO in ctcm_chx_restart");
862 }
863}
864
865/**
866 * Handle error during RX initial handshake (exchange of
867 * 0-length block header)
868 *
869 * fi An instance of a channel statemachine.
870 * event The event, just happened.
871 * arg Generic pointer, casted from channel * upon call.
872 */
873static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg)
874{
875 struct channel *ch = arg;
876 struct net_device *dev = ch->netdev;
877 struct ctcm_priv *priv = dev->priv;
878
879 CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__);
880 if (event == CTC_EVENT_TIMER) {
881 if (!IS_MPCDEV(dev))
882 /* TODO : check if MPC deletes timer somewhere */
883 fsm_deltimer(&ch->timer);
884 ctcm_pr_debug("%s: Timeout during RX init handshake\n",
885 dev->name);
886 if (ch->retry++ < 3)
887 ctcm_chx_restart(fi, event, arg);
888 else {
889 fsm_newstate(fi, CTC_STATE_RXERR);
890 fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
891 }
892 } else
893 ctcm_pr_warn("%s: Error during RX init handshake\n", dev->name);
894}
895
896/**
897 * Notify device statemachine if we gave up initialization
898 * of RX channel.
899 *
900 * fi An instance of a channel statemachine.
901 * event The event, just happened.
902 * arg Generic pointer, casted from channel * upon call.
903 */
904static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg)
905{
906 struct channel *ch = arg;
907 struct net_device *dev = ch->netdev;
908 struct ctcm_priv *priv = dev->priv;
909
910 CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__);
911 fsm_newstate(fi, CTC_STATE_RXERR);
912 ctcm_pr_warn("%s: RX busy. Initialization failed\n", dev->name);
913 fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
914}
915
916/**
917 * Handle RX Unit check remote reset (remote disconnected)
918 *
919 * fi An instance of a channel statemachine.
920 * event The event, just happened.
921 * arg Generic pointer, casted from channel * upon call.
922 */
923static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg)
924{
925 struct channel *ch = arg;
926 struct channel *ch2;
927 struct net_device *dev = ch->netdev;
928 struct ctcm_priv *priv = dev->priv;
929
930 CTCM_DBF_DEV_NAME(TRACE, dev, "Got remote disconnect, re-initializing");
931 fsm_deltimer(&ch->timer);
932 if (do_debug)
933 ctcm_pr_debug("%s: Got remote disconnect, "
934 "re-initializing ...\n", dev->name);
935 /*
936 * Notify device statemachine
937 */
938 fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
939 fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
940
941 fsm_newstate(fi, CTC_STATE_DTERM);
942 ch2 = priv->channel[WRITE];
943 fsm_newstate(ch2->fsm, CTC_STATE_DTERM);
944
945 ccw_device_halt(ch->cdev, (unsigned long)ch);
946 ccw_device_halt(ch2->cdev, (unsigned long)ch2);
947}
948
949/**
950 * Handle error during TX channel initialization.
951 *
952 * fi An instance of a channel statemachine.
953 * event The event, just happened.
954 * arg Generic pointer, casted from channel * upon call.
955 */
956static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg)
957{
958 struct channel *ch = arg;
959 struct net_device *dev = ch->netdev;
960 struct ctcm_priv *priv = dev->priv;
961
962 if (event == CTC_EVENT_TIMER) {
963 fsm_deltimer(&ch->timer);
964 CTCM_DBF_DEV_NAME(ERROR, dev,
965 "Timeout during TX init handshake");
966 if (ch->retry++ < 3)
967 ctcm_chx_restart(fi, event, arg);
968 else {
969 fsm_newstate(fi, CTC_STATE_TXERR);
970 fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
971 }
972 } else {
973 CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
974 "%s : %s error during channel setup state=%s",
975 dev->name, ctc_ch_event_names[event],
976 fsm_getstate_str(fi));
977
978 ctcm_pr_warn("%s: Error during TX init handshake\n", dev->name);
979 }
980}
981
982/**
983 * Handle TX timeout by retrying operation.
984 *
985 * fi An instance of a channel statemachine.
986 * event The event, just happened.
987 * arg Generic pointer, casted from channel * upon call.
988 */
989static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
990{
991 struct channel *ch = arg;
992 struct net_device *dev = ch->netdev;
993 struct ctcm_priv *priv = dev->priv;
994 struct sk_buff *skb;
995
996 if (do_debug)
997 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
998 __FUNCTION__, smp_processor_id(), ch, ch->id);
999
1000 fsm_deltimer(&ch->timer);
1001 if (ch->retry++ > 3) {
1002 struct mpc_group *gptr = priv->mpcg;
1003 ctcm_pr_debug("%s: TX retry failed, restarting channel\n",
1004 dev->name);
1005 fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
1006 /* call restart if not MPC or if MPC and mpcg fsm is ready.
1007 use gptr as mpc indicator */
1008 if (!(gptr && (fsm_getstate(gptr->fsm) != MPCG_STATE_READY)))
1009 ctcm_chx_restart(fi, event, arg);
1010 goto done;
1011 }
1012
1013 ctcm_pr_debug("%s: TX retry %d\n", dev->name, ch->retry);
1014 skb = skb_peek(&ch->io_queue);
1015 if (skb) {
1016 int rc = 0;
1017 unsigned long saveflags = 0;
1018 clear_normalized_cda(&ch->ccw[4]);
1019 ch->ccw[4].count = skb->len;
1020 if (set_normalized_cda(&ch->ccw[4], skb->data)) {
1021 ctcm_pr_debug("%s: IDAL alloc failed, chan restart\n",
1022 dev->name);
1023 fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
1024 ctcm_chx_restart(fi, event, arg);
1025 goto done;
1026 }
1027 fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch);
1028 if (event == CTC_EVENT_TIMER) /* for TIMER not yet locked */
1029 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
1030 /* Such conditional locking is a known problem for
1031 * sparse because its undeterministic in static view.
1032 * Warnings should be ignored here. */
1033 if (do_debug_ccw)
1034 ctcmpc_dumpit((char *)&ch->ccw[3],
1035 sizeof(struct ccw1) * 3);
1036
1037 rc = ccw_device_start(ch->cdev, &ch->ccw[3],
1038 (unsigned long)ch, 0xff, 0);
1039 if (event == CTC_EVENT_TIMER)
1040 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev),
1041 saveflags);
1042 if (rc != 0) {
1043 fsm_deltimer(&ch->timer);
1044 ctcm_ccw_check_rc(ch, rc, "TX in chx_txretry");
1045 ctcm_purge_skb_queue(&ch->io_queue);
1046 }
1047 }
1048done:
1049 return;
1050}
1051
1052/**
1053 * Handle fatal errors during an I/O command.
1054 *
1055 * fi An instance of a channel statemachine.
1056 * event The event, just happened.
1057 * arg Generic pointer, casted from channel * upon call.
1058 */
1059static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg)
1060{
1061 struct channel *ch = arg;
1062 struct net_device *dev = ch->netdev;
1063 struct ctcm_priv *priv = dev->priv;
1064
1065 CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
1066 fsm_deltimer(&ch->timer);
1067 ctcm_pr_warn("%s %s : unrecoverable channel error\n",
1068 CTC_DRIVER_NAME, dev->name);
1069 if (IS_MPC(ch)) {
1070 priv->stats.tx_dropped++;
1071 priv->stats.tx_errors++;
1072 }
1073
1074 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1075 ctcm_pr_debug("%s: RX I/O error\n", dev->name);
1076 fsm_newstate(fi, CTC_STATE_RXERR);
1077 fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
1078 } else {
1079 ctcm_pr_debug("%s: TX I/O error\n", dev->name);
1080 fsm_newstate(fi, CTC_STATE_TXERR);
1081 fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
1082 }
1083}
1084
1085/*
1086 * The ctcm statemachine for a channel.
1087 */
1088const fsm_node ch_fsm[] = {
1089 { CTC_STATE_STOPPED, CTC_EVENT_STOP, ctcm_action_nop },
1090 { CTC_STATE_STOPPED, CTC_EVENT_START, ctcm_chx_start },
1091 { CTC_STATE_STOPPED, CTC_EVENT_FINSTAT, ctcm_action_nop },
1092 { CTC_STATE_STOPPED, CTC_EVENT_MC_FAIL, ctcm_action_nop },
1093
1094 { CTC_STATE_NOTOP, CTC_EVENT_STOP, ctcm_chx_stop },
1095 { CTC_STATE_NOTOP, CTC_EVENT_START, ctcm_action_nop },
1096 { CTC_STATE_NOTOP, CTC_EVENT_FINSTAT, ctcm_action_nop },
1097 { CTC_STATE_NOTOP, CTC_EVENT_MC_FAIL, ctcm_action_nop },
1098 { CTC_STATE_NOTOP, CTC_EVENT_MC_GOOD, ctcm_chx_start },
1099
1100 { CTC_STATE_STARTWAIT, CTC_EVENT_STOP, ctcm_chx_haltio },
1101 { CTC_STATE_STARTWAIT, CTC_EVENT_START, ctcm_action_nop },
1102 { CTC_STATE_STARTWAIT, CTC_EVENT_FINSTAT, ctcm_chx_setmode },
1103 { CTC_STATE_STARTWAIT, CTC_EVENT_TIMER, ctcm_chx_setuperr },
1104 { CTC_STATE_STARTWAIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1105 { CTC_STATE_STARTWAIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1106
1107 { CTC_STATE_STARTRETRY, CTC_EVENT_STOP, ctcm_chx_haltio },
1108 { CTC_STATE_STARTRETRY, CTC_EVENT_TIMER, ctcm_chx_setmode },
1109 { CTC_STATE_STARTRETRY, CTC_EVENT_FINSTAT, ctcm_action_nop },
1110 { CTC_STATE_STARTRETRY, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1111
1112 { CTC_STATE_SETUPWAIT, CTC_EVENT_STOP, ctcm_chx_haltio },
1113 { CTC_STATE_SETUPWAIT, CTC_EVENT_START, ctcm_action_nop },
1114 { CTC_STATE_SETUPWAIT, CTC_EVENT_FINSTAT, chx_firstio },
1115 { CTC_STATE_SETUPWAIT, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
1116 { CTC_STATE_SETUPWAIT, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
1117 { CTC_STATE_SETUPWAIT, CTC_EVENT_TIMER, ctcm_chx_setmode },
1118 { CTC_STATE_SETUPWAIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1119 { CTC_STATE_SETUPWAIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1120
1121 { CTC_STATE_RXINIT, CTC_EVENT_STOP, ctcm_chx_haltio },
1122 { CTC_STATE_RXINIT, CTC_EVENT_START, ctcm_action_nop },
1123 { CTC_STATE_RXINIT, CTC_EVENT_FINSTAT, chx_rxidle },
1124 { CTC_STATE_RXINIT, CTC_EVENT_UC_RCRESET, ctcm_chx_rxiniterr },
1125 { CTC_STATE_RXINIT, CTC_EVENT_UC_RSRESET, ctcm_chx_rxiniterr },
1126 { CTC_STATE_RXINIT, CTC_EVENT_TIMER, ctcm_chx_rxiniterr },
1127 { CTC_STATE_RXINIT, CTC_EVENT_ATTNBUSY, ctcm_chx_rxinitfail },
1128 { CTC_STATE_RXINIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1129 { CTC_STATE_RXINIT, CTC_EVENT_UC_ZERO, chx_firstio },
1130 { CTC_STATE_RXINIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1131
1132 { CTC_STATE_RXIDLE, CTC_EVENT_STOP, ctcm_chx_haltio },
1133 { CTC_STATE_RXIDLE, CTC_EVENT_START, ctcm_action_nop },
1134 { CTC_STATE_RXIDLE, CTC_EVENT_FINSTAT, chx_rx },
1135 { CTC_STATE_RXIDLE, CTC_EVENT_UC_RCRESET, ctcm_chx_rxdisc },
1136 { CTC_STATE_RXIDLE, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1137 { CTC_STATE_RXIDLE, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1138 { CTC_STATE_RXIDLE, CTC_EVENT_UC_ZERO, chx_rx },
1139
1140 { CTC_STATE_TXINIT, CTC_EVENT_STOP, ctcm_chx_haltio },
1141 { CTC_STATE_TXINIT, CTC_EVENT_START, ctcm_action_nop },
1142 { CTC_STATE_TXINIT, CTC_EVENT_FINSTAT, ctcm_chx_txidle },
1143 { CTC_STATE_TXINIT, CTC_EVENT_UC_RCRESET, ctcm_chx_txiniterr },
1144 { CTC_STATE_TXINIT, CTC_EVENT_UC_RSRESET, ctcm_chx_txiniterr },
1145 { CTC_STATE_TXINIT, CTC_EVENT_TIMER, ctcm_chx_txiniterr },
1146 { CTC_STATE_TXINIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1147 { CTC_STATE_TXINIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1148
1149 { CTC_STATE_TXIDLE, CTC_EVENT_STOP, ctcm_chx_haltio },
1150 { CTC_STATE_TXIDLE, CTC_EVENT_START, ctcm_action_nop },
1151 { CTC_STATE_TXIDLE, CTC_EVENT_FINSTAT, chx_firstio },
1152 { CTC_STATE_TXIDLE, CTC_EVENT_UC_RCRESET, ctcm_action_nop },
1153 { CTC_STATE_TXIDLE, CTC_EVENT_UC_RSRESET, ctcm_action_nop },
1154 { CTC_STATE_TXIDLE, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1155 { CTC_STATE_TXIDLE, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1156
1157 { CTC_STATE_TERM, CTC_EVENT_STOP, ctcm_action_nop },
1158 { CTC_STATE_TERM, CTC_EVENT_START, ctcm_chx_restart },
1159 { CTC_STATE_TERM, CTC_EVENT_FINSTAT, ctcm_chx_stopped },
1160 { CTC_STATE_TERM, CTC_EVENT_UC_RCRESET, ctcm_action_nop },
1161 { CTC_STATE_TERM, CTC_EVENT_UC_RSRESET, ctcm_action_nop },
1162 { CTC_STATE_TERM, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1163
1164 { CTC_STATE_DTERM, CTC_EVENT_STOP, ctcm_chx_haltio },
1165 { CTC_STATE_DTERM, CTC_EVENT_START, ctcm_chx_restart },
1166 { CTC_STATE_DTERM, CTC_EVENT_FINSTAT, ctcm_chx_setmode },
1167 { CTC_STATE_DTERM, CTC_EVENT_UC_RCRESET, ctcm_action_nop },
1168 { CTC_STATE_DTERM, CTC_EVENT_UC_RSRESET, ctcm_action_nop },
1169 { CTC_STATE_DTERM, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1170
1171 { CTC_STATE_TX, CTC_EVENT_STOP, ctcm_chx_haltio },
1172 { CTC_STATE_TX, CTC_EVENT_START, ctcm_action_nop },
1173 { CTC_STATE_TX, CTC_EVENT_FINSTAT, chx_txdone },
1174 { CTC_STATE_TX, CTC_EVENT_UC_RCRESET, ctcm_chx_txretry },
1175 { CTC_STATE_TX, CTC_EVENT_UC_RSRESET, ctcm_chx_txretry },
1176 { CTC_STATE_TX, CTC_EVENT_TIMER, ctcm_chx_txretry },
1177 { CTC_STATE_TX, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1178 { CTC_STATE_TX, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1179
1180 { CTC_STATE_RXERR, CTC_EVENT_STOP, ctcm_chx_haltio },
1181 { CTC_STATE_TXERR, CTC_EVENT_STOP, ctcm_chx_haltio },
1182 { CTC_STATE_TXERR, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1183 { CTC_STATE_RXERR, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1184};
1185
1186int ch_fsm_len = ARRAY_SIZE(ch_fsm);
1187
1188/*
1189 * MPC actions for mpc channel statemachine
1190 * handling of MPC protocol requires extra
1191 * statemachine and actions which are prefixed ctcmpc_ .
1192 * The ctc_ch_states and ctc_ch_state_names,
1193 * ctc_ch_events and ctc_ch_event_names share the ctcm definitions
1194 * which are expanded by some elements.
1195 */
1196
1197/*
1198 * Actions for mpc channel statemachine.
1199 */
1200
1201/**
1202 * Normal data has been send. Free the corresponding
1203 * skb (it's in io_queue), reset dev->tbusy and
1204 * revert to idle state.
1205 *
1206 * fi An instance of a channel statemachine.
1207 * event The event, just happened.
1208 * arg Generic pointer, casted from channel * upon call.
1209 */
1210static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
1211{
1212 struct channel *ch = arg;
1213 struct net_device *dev = ch->netdev;
1214 struct ctcm_priv *priv = dev->priv;
1215 struct mpc_group *grp = priv->mpcg;
1216 struct sk_buff *skb;
1217 int first = 1;
1218 int i;
1219 struct timespec done_stamp;
1220 __u32 data_space;
1221 unsigned long duration;
1222 struct sk_buff *peekskb;
1223 int rc;
1224 struct th_header *header;
1225 struct pdu *p_header;
1226
1227 if (do_debug)
1228 ctcm_pr_debug("%s cp:%i enter: %s()\n",
1229 dev->name, smp_processor_id(), __FUNCTION__);
1230
1231 done_stamp = current_kernel_time(); /* xtime */
1232 duration = (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000
1233 + (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
1234 if (duration > ch->prof.tx_time)
1235 ch->prof.tx_time = duration;
1236
1237 if (ch->irb->scsw.count != 0)
1238 ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n",
1239 dev->name, ch->irb->scsw.count);
1240 fsm_deltimer(&ch->timer);
1241 while ((skb = skb_dequeue(&ch->io_queue))) {
1242 priv->stats.tx_packets++;
1243 priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH;
1244 if (first) {
1245 priv->stats.tx_bytes += 2;
1246 first = 0;
1247 }
1248 atomic_dec(&skb->users);
1249 dev_kfree_skb_irq(skb);
1250 }
1251 spin_lock(&ch->collect_lock);
1252 clear_normalized_cda(&ch->ccw[4]);
1253
1254 if ((ch->collect_len <= 0) || (grp->in_sweep != 0)) {
1255 spin_unlock(&ch->collect_lock);
1256 fsm_newstate(fi, CTC_STATE_TXIDLE);
1257 goto done;
1258 }
1259
1260 if (ctcm_checkalloc_buffer(ch)) {
1261 spin_unlock(&ch->collect_lock);
1262 goto done;
1263 }
1264 ch->trans_skb->data = ch->trans_skb_data;
1265 skb_reset_tail_pointer(ch->trans_skb);
1266 ch->trans_skb->len = 0;
1267 if (ch->prof.maxmulti < (ch->collect_len + TH_HEADER_LENGTH))
1268 ch->prof.maxmulti = ch->collect_len + TH_HEADER_LENGTH;
1269 if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))
1270 ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);
1271 i = 0;
1272
1273 if (do_debug_data)
1274 ctcm_pr_debug("ctcmpc: %s() building "
1275 "trans_skb from collect_q \n", __FUNCTION__);
1276
1277 data_space = grp->group_max_buflen - TH_HEADER_LENGTH;
1278
1279 if (do_debug_data)
1280 ctcm_pr_debug("ctcmpc: %s() building trans_skb from collect_q"
1281 " data_space:%04x\n", __FUNCTION__, data_space);
1282 p_header = NULL;
1283 while ((skb = skb_dequeue(&ch->collect_queue))) {
1284 memcpy(skb_put(ch->trans_skb, skb->len), skb->data, skb->len);
1285 p_header = (struct pdu *)
1286 (skb_tail_pointer(ch->trans_skb) - skb->len);
1287 p_header->pdu_flag = 0x00;
1288 if (skb->protocol == ntohs(ETH_P_SNAP))
1289 p_header->pdu_flag |= 0x60;
1290 else
1291 p_header->pdu_flag |= 0x20;
1292
1293 if (do_debug_data) {
1294 ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n",
1295 __FUNCTION__, ch->trans_skb->len);
1296 ctcm_pr_debug("ctcmpc: %s() pdu header and data"
1297 " for up to 32 bytes sent to vtam\n",
1298 __FUNCTION__);
1299 ctcmpc_dumpit((char *)p_header,
1300 min_t(int, skb->len, 32));
1301 }
1302 ch->collect_len -= skb->len;
1303 data_space -= skb->len;
1304 priv->stats.tx_packets++;
1305 priv->stats.tx_bytes += skb->len;
1306 atomic_dec(&skb->users);
1307 dev_kfree_skb_any(skb);
1308 peekskb = skb_peek(&ch->collect_queue);
1309 if (peekskb->len > data_space)
1310 break;
1311 i++;
1312 }
1313 /* p_header points to the last one we handled */
1314 if (p_header)
1315 p_header->pdu_flag |= PDU_LAST; /*Say it's the last one*/
1316 header = kzalloc(TH_HEADER_LENGTH, gfp_type());
1317
1318 if (!header) {
1319 printk(KERN_WARNING "ctcmpc: OUT OF MEMORY IN %s()"
1320 ": Data Lost \n", __FUNCTION__);
1321 spin_unlock(&ch->collect_lock);
1322 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
1323 goto done;
1324 }
1325
1326 header->th_ch_flag = TH_HAS_PDU; /* Normal data */
1327 ch->th_seq_num++;
1328 header->th_seq_num = ch->th_seq_num;
1329
1330 if (do_debug_data)
1331 ctcm_pr_debug("%s: ToVTAM_th_seq= %08x\n" ,
1332 __FUNCTION__, ch->th_seq_num);
1333
1334 memcpy(skb_push(ch->trans_skb, TH_HEADER_LENGTH), header,
1335 TH_HEADER_LENGTH); /* put the TH on the packet */
1336
1337 kfree(header);
1338
1339 if (do_debug_data) {
1340 ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n",
1341 __FUNCTION__, ch->trans_skb->len);
1342
1343 ctcm_pr_debug("ctcmpc: %s() up-to-50 bytes of trans_skb "
1344 "data to vtam from collect_q\n", __FUNCTION__);
1345 ctcmpc_dumpit((char *)ch->trans_skb->data,
1346 min_t(int, ch->trans_skb->len, 50));
1347 }
1348
1349 spin_unlock(&ch->collect_lock);
1350 clear_normalized_cda(&ch->ccw[1]);
1351 if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
1352 dev_kfree_skb_any(ch->trans_skb);
1353 ch->trans_skb = NULL;
1354 printk(KERN_WARNING
1355 "ctcmpc: %s()CCW failure - data lost\n",
1356 __FUNCTION__);
1357 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
1358 return;
1359 }
1360 ch->ccw[1].count = ch->trans_skb->len;
1361 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
1362 ch->prof.send_stamp = current_kernel_time(); /* xtime */
1363 if (do_debug_ccw)
1364 ctcmpc_dumpit((char *)&ch->ccw[0], sizeof(struct ccw1) * 3);
1365 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
1366 (unsigned long)ch, 0xff, 0);
1367 ch->prof.doios_multi++;
1368 if (rc != 0) {
1369 priv->stats.tx_dropped += i;
1370 priv->stats.tx_errors += i;
1371 fsm_deltimer(&ch->timer);
1372 ctcm_ccw_check_rc(ch, rc, "chained TX");
1373 }
1374done:
1375 ctcm_clear_busy(dev);
1376 ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
1377 return;
1378}
1379
1380/**
1381 * Got normal data, check for sanity, queue it up, allocate new buffer
1382 * trigger bottom half, and initiate next read.
1383 *
1384 * fi An instance of a channel statemachine.
1385 * event The event, just happened.
1386 * arg Generic pointer, casted from channel * upon call.
1387 */
1388static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
1389{
1390 struct channel *ch = arg;
1391 struct net_device *dev = ch->netdev;
1392 struct ctcm_priv *priv = dev->priv;
1393 struct mpc_group *grp = priv->mpcg;
1394 struct sk_buff *skb = ch->trans_skb;
1395 struct sk_buff *new_skb;
1396 unsigned long saveflags = 0; /* avoids compiler warning */
1397 int len = ch->max_bufsize - ch->irb->scsw.count;
1398
1399 if (do_debug_data) {
1400 CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx %s cp:%i %s\n",
1401 dev->name, smp_processor_id(), ch->id);
1402 CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx: maxbuf: %04x "
1403 "len: %04x\n", ch->max_bufsize, len);
1404 }
1405 fsm_deltimer(&ch->timer);
1406
1407 if (skb == NULL) {
1408 ctcm_pr_debug("ctcmpc exit: %s() TRANS_SKB = NULL \n",
1409 __FUNCTION__);
1410 goto again;
1411 }
1412
1413 if (len < TH_HEADER_LENGTH) {
1414 ctcm_pr_info("%s: got packet with invalid length %d\n",
1415 dev->name, len);
1416 priv->stats.rx_dropped++;
1417 priv->stats.rx_length_errors++;
1418 } else {
1419 /* must have valid th header or game over */
1420 __u32 block_len = len;
1421 len = TH_HEADER_LENGTH + XID2_LENGTH + 4;
1422 new_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC);
1423
1424 if (new_skb == NULL) {
1425 printk(KERN_INFO "ctcmpc:%s() NEW_SKB = NULL\n",
1426 __FUNCTION__);
1427 printk(KERN_WARNING "ctcmpc: %s() MEMORY ALLOC FAILED"
1428 " - DATA LOST - MPC FAILED\n",
1429 __FUNCTION__);
1430 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
1431 goto again;
1432 }
1433 switch (fsm_getstate(grp->fsm)) {
1434 case MPCG_STATE_RESET:
1435 case MPCG_STATE_INOP:
1436 dev_kfree_skb_any(new_skb);
1437 break;
1438 case MPCG_STATE_FLOWC:
1439 case MPCG_STATE_READY:
1440 memcpy(skb_put(new_skb, block_len),
1441 skb->data, block_len);
1442 skb_queue_tail(&ch->io_queue, new_skb);
1443 tasklet_schedule(&ch->ch_tasklet);
1444 break;
1445 default:
1446 memcpy(skb_put(new_skb, len), skb->data, len);
1447 skb_queue_tail(&ch->io_queue, new_skb);
1448 tasklet_hi_schedule(&ch->ch_tasklet);
1449 break;
1450 }
1451 }
1452
1453again:
1454 switch (fsm_getstate(grp->fsm)) {
1455 int rc, dolock;
1456 case MPCG_STATE_FLOWC:
1457 case MPCG_STATE_READY:
1458 if (ctcm_checkalloc_buffer(ch))
1459 break;
1460 ch->trans_skb->data = ch->trans_skb_data;
1461 skb_reset_tail_pointer(ch->trans_skb);
1462 ch->trans_skb->len = 0;
1463 ch->ccw[1].count = ch->max_bufsize;
1464 if (do_debug_ccw)
1465 ctcmpc_dumpit((char *)&ch->ccw[0],
1466 sizeof(struct ccw1) * 3);
1467 dolock = !in_irq();
1468 if (dolock)
1469 spin_lock_irqsave(
1470 get_ccwdev_lock(ch->cdev), saveflags);
1471 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
1472 (unsigned long)ch, 0xff, 0);
1473 if (dolock) /* see remark about conditional locking */
1474 spin_unlock_irqrestore(
1475 get_ccwdev_lock(ch->cdev), saveflags);
1476 if (rc != 0)
1477 ctcm_ccw_check_rc(ch, rc, "normal RX");
1478 default:
1479 break;
1480 }
1481
1482 if (do_debug)
1483 ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
1484 dev->name, __FUNCTION__, ch, ch->id);
1485
1486}
1487
1488/**
1489 * Initialize connection by sending a __u16 of value 0.
1490 *
1491 * fi An instance of a channel statemachine.
1492 * event The event, just happened.
1493 * arg Generic pointer, casted from channel * upon call.
1494 */
1495static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg)
1496{
1497 struct channel *ch = arg;
1498 struct net_device *dev = ch->netdev;
1499 struct ctcm_priv *priv = dev->priv;
1500
1501 if (do_debug) {
1502 struct mpc_group *gptr = priv->mpcg;
1503 ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
1504 __FUNCTION__, ch, ch->id);
1505 ctcm_pr_debug("%s() %s chstate:%i grpstate:%i chprotocol:%i\n",
1506 __FUNCTION__, ch->id, fsm_getstate(fi),
1507 fsm_getstate(gptr->fsm), ch->protocol);
1508 }
1509 if (fsm_getstate(fi) == CTC_STATE_TXIDLE)
1510 MPC_DBF_DEV_NAME(TRACE, dev, "remote side issued READ? ");
1511
1512 fsm_deltimer(&ch->timer);
1513 if (ctcm_checkalloc_buffer(ch))
1514 goto done;
1515
1516 switch (fsm_getstate(fi)) {
1517 case CTC_STATE_STARTRETRY:
1518 case CTC_STATE_SETUPWAIT:
1519 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1520 ctcmpc_chx_rxidle(fi, event, arg);
1521 } else {
1522 fsm_newstate(fi, CTC_STATE_TXIDLE);
1523 fsm_event(priv->fsm, DEV_EVENT_TXUP, dev);
1524 }
1525 goto done;
1526 default:
1527 break;
1528 };
1529
1530 fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == READ)
1531 ? CTC_STATE_RXINIT : CTC_STATE_TXINIT);
1532
1533done:
1534 if (do_debug)
1535 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
1536 __FUNCTION__, ch, ch->id);
1537 return;
1538}
1539
1540/**
1541 * Got initial data, check it. If OK,
1542 * notify device statemachine that we are up and
1543 * running.
1544 *
1545 * fi An instance of a channel statemachine.
1546 * event The event, just happened.
1547 * arg Generic pointer, casted from channel * upon call.
1548 */
1549void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
1550{
1551 struct channel *ch = arg;
1552 struct net_device *dev = ch->netdev;
1553 struct ctcm_priv *priv = dev->priv;
1554 struct mpc_group *grp = priv->mpcg;
1555 int rc;
1556 unsigned long saveflags = 0; /* avoids compiler warning */
1557
1558 fsm_deltimer(&ch->timer);
1559 ctcm_pr_debug("%s cp:%i enter: %s()\n",
1560 dev->name, smp_processor_id(), __FUNCTION__);
1561 if (do_debug)
1562 ctcm_pr_debug("%s() %s chstate:%i grpstate:%i\n",
1563 __FUNCTION__, ch->id,
1564 fsm_getstate(fi), fsm_getstate(grp->fsm));
1565
1566 fsm_newstate(fi, CTC_STATE_RXIDLE);
1567 /* XID processing complete */
1568
1569 switch (fsm_getstate(grp->fsm)) {
1570 case MPCG_STATE_FLOWC:
1571 case MPCG_STATE_READY:
1572 if (ctcm_checkalloc_buffer(ch))
1573 goto done;
1574 ch->trans_skb->data = ch->trans_skb_data;
1575 skb_reset_tail_pointer(ch->trans_skb);
1576 ch->trans_skb->len = 0;
1577 ch->ccw[1].count = ch->max_bufsize;
1578 if (do_debug_ccw)
1579 ctcmpc_dumpit((char *)&ch->ccw[0],
1580 sizeof(struct ccw1) * 3);
1581 if (event == CTC_EVENT_START)
1582 /* see remark about conditional locking */
1583 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
1584 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
1585 (unsigned long)ch, 0xff, 0);
1586 if (event == CTC_EVENT_START)
1587 spin_unlock_irqrestore(
1588 get_ccwdev_lock(ch->cdev), saveflags);
1589 if (rc != 0) {
1590 fsm_newstate(fi, CTC_STATE_RXINIT);
1591 ctcm_ccw_check_rc(ch, rc, "initial RX");
1592 goto done;
1593 }
1594 break;
1595 default:
1596 break;
1597 }
1598
1599 fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
1600done:
1601 if (do_debug)
1602 ctcm_pr_debug("ctcmpc exit: %s %s()\n",
1603 dev->name, __FUNCTION__);
1604 return;
1605}
1606
1607/*
1608 * ctcmpc channel FSM action
1609 * called from several points in ctcmpc_ch_fsm
1610 * ctcmpc only
1611 */
1612static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg)
1613{
1614 struct channel *ch = arg;
1615 struct net_device *dev = ch->netdev;
1616 struct ctcm_priv *priv = dev->priv;
1617 struct mpc_group *grp = priv->mpcg;
1618
1619 if (do_debug) {
1620 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s"
1621 "GrpState:%s ChState:%s\n",
1622 __FUNCTION__, smp_processor_id(), ch, ch->id,
1623 fsm_getstate_str(grp->fsm),
1624 fsm_getstate_str(ch->fsm));
1625 }
1626
1627 switch (fsm_getstate(grp->fsm)) {
1628 case MPCG_STATE_XID2INITW:
1629 /* ok..start yside xid exchanges */
1630 if (!ch->in_mpcgroup)
1631 break;
1632 if (fsm_getstate(ch->fsm) == CH_XID0_PENDING) {
1633 fsm_deltimer(&grp->timer);
1634 fsm_addtimer(&grp->timer,
1635 MPC_XID_TIMEOUT_VALUE,
1636 MPCG_EVENT_TIMER, dev);
1637 fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
1638
1639 } else if (fsm_getstate(ch->fsm) < CH_XID7_PENDING1)
1640 /* attn rcvd before xid0 processed via bh */
1641 fsm_newstate(ch->fsm, CH_XID7_PENDING1);
1642 break;
1643 case MPCG_STATE_XID2INITX:
1644 case MPCG_STATE_XID0IOWAIT:
1645 case MPCG_STATE_XID0IOWAIX:
1646 /* attn rcvd before xid0 processed on ch
1647 but mid-xid0 processing for group */
1648 if (fsm_getstate(ch->fsm) < CH_XID7_PENDING1)
1649 fsm_newstate(ch->fsm, CH_XID7_PENDING1);
1650 break;
1651 case MPCG_STATE_XID7INITW:
1652 case MPCG_STATE_XID7INITX:
1653 case MPCG_STATE_XID7INITI:
1654 case MPCG_STATE_XID7INITZ:
1655 switch (fsm_getstate(ch->fsm)) {
1656 case CH_XID7_PENDING:
1657 fsm_newstate(ch->fsm, CH_XID7_PENDING1);
1658 break;
1659 case CH_XID7_PENDING2:
1660 fsm_newstate(ch->fsm, CH_XID7_PENDING3);
1661 break;
1662 }
1663 fsm_event(grp->fsm, MPCG_EVENT_XID7DONE, dev);
1664 break;
1665 }
1666
1667 if (do_debug)
1668 ctcm_pr_debug("ctcmpc exit : %s(): cp=%i ch=0x%p id=%s\n",
1669 __FUNCTION__, smp_processor_id(), ch, ch->id);
1670 return;
1671
1672}
1673
1674/*
1675 * ctcmpc channel FSM action
1676 * called from one point in ctcmpc_ch_fsm
1677 * ctcmpc only
1678 */
1679static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg)
1680{
1681 struct channel *ch = arg;
1682 struct net_device *dev = ch->netdev;
1683 struct ctcm_priv *priv = dev->priv;
1684 struct mpc_group *grp = priv->mpcg;
1685
1686 ctcm_pr_debug("ctcmpc enter: %s %s() %s \nGrpState:%s ChState:%s\n",
1687 dev->name,
1688 __FUNCTION__, ch->id,
1689 fsm_getstate_str(grp->fsm),
1690 fsm_getstate_str(ch->fsm));
1691
1692 fsm_deltimer(&ch->timer);
1693
1694 switch (fsm_getstate(grp->fsm)) {
1695 case MPCG_STATE_XID0IOWAIT:
1696 /* vtam wants to be primary.start yside xid exchanges*/
1697 /* only receive one attn-busy at a time so must not */
1698 /* change state each time */
1699 grp->changed_side = 1;
1700 fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);
1701 break;
1702 case MPCG_STATE_XID2INITW:
1703 if (grp->changed_side == 1) {
1704 grp->changed_side = 2;
1705 break;
1706 }
1707 /* process began via call to establish_conn */
1708 /* so must report failure instead of reverting */
1709 /* back to ready-for-xid passive state */
1710 if (grp->estconnfunc)
1711 goto done;
1712 /* this attnbusy is NOT the result of xside xid */
1713 /* collisions so yside must have been triggered */
1714 /* by an ATTN that was not intended to start XID */
1715 /* processing. Revert back to ready-for-xid and */
1716 /* wait for ATTN interrupt to signal xid start */
1717 if (fsm_getstate(ch->fsm) == CH_XID0_INPROGRESS) {
1718 fsm_newstate(ch->fsm, CH_XID0_PENDING) ;
1719 fsm_deltimer(&grp->timer);
1720 goto done;
1721 }
1722 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1723 goto done;
1724 case MPCG_STATE_XID2INITX:
1725 /* XID2 was received before ATTN Busy for second
1726 channel.Send yside xid for second channel.
1727 */
1728 if (grp->changed_side == 1) {
1729 grp->changed_side = 2;
1730 break;
1731 }
1732 case MPCG_STATE_XID0IOWAIX:
1733 case MPCG_STATE_XID7INITW:
1734 case MPCG_STATE_XID7INITX:
1735 case MPCG_STATE_XID7INITI:
1736 case MPCG_STATE_XID7INITZ:
1737 default:
1738 /* multiple attn-busy indicates too out-of-sync */
1739 /* and they are certainly not being received as part */
1740 /* of valid mpc group negotiations.. */
1741 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1742 goto done;
1743 }
1744
1745 if (grp->changed_side == 1) {
1746 fsm_deltimer(&grp->timer);
1747 fsm_addtimer(&grp->timer, MPC_XID_TIMEOUT_VALUE,
1748 MPCG_EVENT_TIMER, dev);
1749 }
1750 if (ch->in_mpcgroup)
1751 fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
1752 else
1753 printk(KERN_WARNING "ctcmpc: %s() Not all channels have"
1754 " been added to group\n", __FUNCTION__);
1755
1756done:
1757 if (do_debug)
1758 ctcm_pr_debug("ctcmpc exit : %s()%s ch=0x%p id=%s\n",
1759 __FUNCTION__, dev->name, ch, ch->id);
1760
1761 return;
1762
1763}
1764
1765/*
1766 * ctcmpc channel FSM action
1767 * called from several points in ctcmpc_ch_fsm
1768 * ctcmpc only
1769 */
1770static void ctcmpc_chx_resend(fsm_instance *fsm, int event, void *arg)
1771{
1772 struct channel *ch = arg;
1773 struct net_device *dev = ch->netdev;
1774 struct ctcm_priv *priv = dev->priv;
1775 struct mpc_group *grp = priv->mpcg;
1776
1777 ctcm_pr_debug("ctcmpc enter: %s %s() %s \nGrpState:%s ChState:%s\n",
1778 dev->name, __FUNCTION__, ch->id,
1779 fsm_getstate_str(grp->fsm),
1780 fsm_getstate_str(ch->fsm));
1781
1782 fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
1783
1784 return;
1785}
1786
1787/*
1788 * ctcmpc channel FSM action
1789 * called from several points in ctcmpc_ch_fsm
1790 * ctcmpc only
1791 */
1792static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
1793{
1794 struct channel *ach = arg;
1795 struct net_device *dev = ach->netdev;
1796 struct ctcm_priv *priv = dev->priv;
1797 struct mpc_group *grp = priv->mpcg;
1798 struct channel *wch = priv->channel[WRITE];
1799 struct channel *rch = priv->channel[READ];
1800 struct sk_buff *skb;
1801 struct th_sweep *header;
1802 int rc = 0;
1803 unsigned long saveflags = 0;
1804
1805 if (do_debug)
1806 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
1807 __FUNCTION__, smp_processor_id(), ach, ach->id);
1808
1809 if (grp->in_sweep == 0)
1810 goto done;
1811
1812 if (do_debug_data) {
1813 ctcm_pr_debug("ctcmpc: %s() 1: ToVTAM_th_seq= %08x\n" ,
1814 __FUNCTION__, wch->th_seq_num);
1815 ctcm_pr_debug("ctcmpc: %s() 1: FromVTAM_th_seq= %08x\n" ,
1816 __FUNCTION__, rch->th_seq_num);
1817 }
1818
1819 if (fsm_getstate(wch->fsm) != CTC_STATE_TXIDLE) {
1820 /* give the previous IO time to complete */
1821 fsm_addtimer(&wch->sweep_timer,
1822 200, CTC_EVENT_RSWEEP_TIMER, wch);
1823 goto done;
1824 }
1825
1826 skb = skb_dequeue(&wch->sweep_queue);
1827 if (!skb)
1828 goto done;
1829
1830 if (set_normalized_cda(&wch->ccw[4], skb->data)) {
1831 grp->in_sweep = 0;
1832 ctcm_clear_busy_do(dev);
1833 dev_kfree_skb_any(skb);
1834 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1835 goto done;
1836 } else {
1837 atomic_inc(&skb->users);
1838 skb_queue_tail(&wch->io_queue, skb);
1839 }
1840
1841 /* send out the sweep */
1842 wch->ccw[4].count = skb->len;
1843
1844 header = (struct th_sweep *)skb->data;
1845 switch (header->th.th_ch_flag) {
1846 case TH_SWEEP_REQ:
1847 grp->sweep_req_pend_num--;
1848 break;
1849 case TH_SWEEP_RESP:
1850 grp->sweep_rsp_pend_num--;
1851 break;
1852 }
1853
1854 header->sw.th_last_seq = wch->th_seq_num;
1855
1856 if (do_debug_ccw)
1857 ctcmpc_dumpit((char *)&wch->ccw[3], sizeof(struct ccw1) * 3);
1858
1859 ctcm_pr_debug("ctcmpc: %s() sweep packet\n", __FUNCTION__);
1860 ctcmpc_dumpit((char *)header, TH_SWEEP_LENGTH);
1861
1862 fsm_addtimer(&wch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, wch);
1863 fsm_newstate(wch->fsm, CTC_STATE_TX);
1864
1865 spin_lock_irqsave(get_ccwdev_lock(wch->cdev), saveflags);
1866 wch->prof.send_stamp = current_kernel_time(); /* xtime */
1867 rc = ccw_device_start(wch->cdev, &wch->ccw[3],
1868 (unsigned long) wch, 0xff, 0);
1869 spin_unlock_irqrestore(get_ccwdev_lock(wch->cdev), saveflags);
1870
1871 if ((grp->sweep_req_pend_num == 0) &&
1872 (grp->sweep_rsp_pend_num == 0)) {
1873 grp->in_sweep = 0;
1874 rch->th_seq_num = 0x00;
1875 wch->th_seq_num = 0x00;
1876 ctcm_clear_busy_do(dev);
1877 }
1878
1879 if (do_debug_data) {
1880 ctcm_pr_debug("ctcmpc: %s()2: ToVTAM_th_seq= %08x\n" ,
1881 __FUNCTION__, wch->th_seq_num);
1882 ctcm_pr_debug("ctcmpc: %s()2: FromVTAM_th_seq= %08x\n" ,
1883 __FUNCTION__, rch->th_seq_num);
1884 }
1885
1886 if (rc != 0)
1887 ctcm_ccw_check_rc(wch, rc, "send sweep");
1888
1889done:
1890 if (do_debug)
1891 ctcm_pr_debug("ctcmpc exit: %s() %s\n", __FUNCTION__, ach->id);
1892 return;
1893}
1894
1895
1896/*
1897 * The ctcmpc statemachine for a channel.
1898 */
1899
1900const fsm_node ctcmpc_ch_fsm[] = {
1901 { CTC_STATE_STOPPED, CTC_EVENT_STOP, ctcm_action_nop },
1902 { CTC_STATE_STOPPED, CTC_EVENT_START, ctcm_chx_start },
1903 { CTC_STATE_STOPPED, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1904 { CTC_STATE_STOPPED, CTC_EVENT_FINSTAT, ctcm_action_nop },
1905 { CTC_STATE_STOPPED, CTC_EVENT_MC_FAIL, ctcm_action_nop },
1906
1907 { CTC_STATE_NOTOP, CTC_EVENT_STOP, ctcm_chx_stop },
1908 { CTC_STATE_NOTOP, CTC_EVENT_START, ctcm_action_nop },
1909 { CTC_STATE_NOTOP, CTC_EVENT_FINSTAT, ctcm_action_nop },
1910 { CTC_STATE_NOTOP, CTC_EVENT_MC_FAIL, ctcm_action_nop },
1911 { CTC_STATE_NOTOP, CTC_EVENT_MC_GOOD, ctcm_chx_start },
1912 { CTC_STATE_NOTOP, CTC_EVENT_UC_RCRESET, ctcm_chx_stop },
1913 { CTC_STATE_NOTOP, CTC_EVENT_UC_RSRESET, ctcm_chx_stop },
1914 { CTC_STATE_NOTOP, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1915
1916 { CTC_STATE_STARTWAIT, CTC_EVENT_STOP, ctcm_chx_haltio },
1917 { CTC_STATE_STARTWAIT, CTC_EVENT_START, ctcm_action_nop },
1918 { CTC_STATE_STARTWAIT, CTC_EVENT_FINSTAT, ctcm_chx_setmode },
1919 { CTC_STATE_STARTWAIT, CTC_EVENT_TIMER, ctcm_chx_setuperr },
1920 { CTC_STATE_STARTWAIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1921 { CTC_STATE_STARTWAIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1922
1923 { CTC_STATE_STARTRETRY, CTC_EVENT_STOP, ctcm_chx_haltio },
1924 { CTC_STATE_STARTRETRY, CTC_EVENT_TIMER, ctcm_chx_setmode },
1925 { CTC_STATE_STARTRETRY, CTC_EVENT_FINSTAT, ctcm_chx_setmode },
1926 { CTC_STATE_STARTRETRY, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1927 { CTC_STATE_STARTRETRY, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1928
1929 { CTC_STATE_SETUPWAIT, CTC_EVENT_STOP, ctcm_chx_haltio },
1930 { CTC_STATE_SETUPWAIT, CTC_EVENT_START, ctcm_action_nop },
1931 { CTC_STATE_SETUPWAIT, CTC_EVENT_FINSTAT, ctcmpc_chx_firstio },
1932 { CTC_STATE_SETUPWAIT, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
1933 { CTC_STATE_SETUPWAIT, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
1934 { CTC_STATE_SETUPWAIT, CTC_EVENT_TIMER, ctcm_chx_setmode },
1935 { CTC_STATE_SETUPWAIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1936 { CTC_STATE_SETUPWAIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1937
1938 { CTC_STATE_RXINIT, CTC_EVENT_STOP, ctcm_chx_haltio },
1939 { CTC_STATE_RXINIT, CTC_EVENT_START, ctcm_action_nop },
1940 { CTC_STATE_RXINIT, CTC_EVENT_FINSTAT, ctcmpc_chx_rxidle },
1941 { CTC_STATE_RXINIT, CTC_EVENT_UC_RCRESET, ctcm_chx_rxiniterr },
1942 { CTC_STATE_RXINIT, CTC_EVENT_UC_RSRESET, ctcm_chx_rxiniterr },
1943 { CTC_STATE_RXINIT, CTC_EVENT_TIMER, ctcm_chx_rxiniterr },
1944 { CTC_STATE_RXINIT, CTC_EVENT_ATTNBUSY, ctcm_chx_rxinitfail },
1945 { CTC_STATE_RXINIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1946 { CTC_STATE_RXINIT, CTC_EVENT_UC_ZERO, ctcmpc_chx_firstio },
1947 { CTC_STATE_RXINIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1948
1949 { CH_XID0_PENDING, CTC_EVENT_FINSTAT, ctcm_action_nop },
1950 { CH_XID0_PENDING, CTC_EVENT_ATTN, ctcmpc_chx_attn },
1951 { CH_XID0_PENDING, CTC_EVENT_STOP, ctcm_chx_haltio },
1952 { CH_XID0_PENDING, CTC_EVENT_START, ctcm_action_nop },
1953 { CH_XID0_PENDING, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1954 { CH_XID0_PENDING, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1955 { CH_XID0_PENDING, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
1956 { CH_XID0_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
1957 { CH_XID0_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
1958 { CH_XID0_PENDING, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal },
1959
1960 { CH_XID0_INPROGRESS, CTC_EVENT_FINSTAT, ctcmpc_chx_rx },
1961 { CH_XID0_INPROGRESS, CTC_EVENT_ATTN, ctcmpc_chx_attn },
1962 { CH_XID0_INPROGRESS, CTC_EVENT_STOP, ctcm_chx_haltio },
1963 { CH_XID0_INPROGRESS, CTC_EVENT_START, ctcm_action_nop },
1964 { CH_XID0_INPROGRESS, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1965 { CH_XID0_INPROGRESS, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1966 { CH_XID0_INPROGRESS, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx },
1967 { CH_XID0_INPROGRESS, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
1968 { CH_XID0_INPROGRESS, CTC_EVENT_ATTNBUSY, ctcmpc_chx_attnbusy },
1969 { CH_XID0_INPROGRESS, CTC_EVENT_TIMER, ctcmpc_chx_resend },
1970 { CH_XID0_INPROGRESS, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
1971
1972 { CH_XID7_PENDING, CTC_EVENT_FINSTAT, ctcmpc_chx_rx },
1973 { CH_XID7_PENDING, CTC_EVENT_ATTN, ctcmpc_chx_attn },
1974 { CH_XID7_PENDING, CTC_EVENT_STOP, ctcm_chx_haltio },
1975 { CH_XID7_PENDING, CTC_EVENT_START, ctcm_action_nop },
1976 { CH_XID7_PENDING, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1977 { CH_XID7_PENDING, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1978 { CH_XID7_PENDING, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx },
1979 { CH_XID7_PENDING, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
1980 { CH_XID7_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
1981 { CH_XID7_PENDING, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
1982 { CH_XID7_PENDING, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal },
1983 { CH_XID7_PENDING, CTC_EVENT_TIMER, ctcmpc_chx_resend },
1984 { CH_XID7_PENDING, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
1985
1986 { CH_XID7_PENDING1, CTC_EVENT_FINSTAT, ctcmpc_chx_rx },
1987 { CH_XID7_PENDING1, CTC_EVENT_ATTN, ctcmpc_chx_attn },
1988 { CH_XID7_PENDING1, CTC_EVENT_STOP, ctcm_chx_haltio },
1989 { CH_XID7_PENDING1, CTC_EVENT_START, ctcm_action_nop },
1990 { CH_XID7_PENDING1, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
1991 { CH_XID7_PENDING1, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
1992 { CH_XID7_PENDING1, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx },
1993 { CH_XID7_PENDING1, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
1994 { CH_XID7_PENDING1, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
1995 { CH_XID7_PENDING1, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal },
1996 { CH_XID7_PENDING1, CTC_EVENT_TIMER, ctcmpc_chx_resend },
1997 { CH_XID7_PENDING1, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
1998
1999 { CH_XID7_PENDING2, CTC_EVENT_FINSTAT, ctcmpc_chx_rx },
2000 { CH_XID7_PENDING2, CTC_EVENT_ATTN, ctcmpc_chx_attn },
2001 { CH_XID7_PENDING2, CTC_EVENT_STOP, ctcm_chx_haltio },
2002 { CH_XID7_PENDING2, CTC_EVENT_START, ctcm_action_nop },
2003 { CH_XID7_PENDING2, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2004 { CH_XID7_PENDING2, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2005 { CH_XID7_PENDING2, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx },
2006 { CH_XID7_PENDING2, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
2007 { CH_XID7_PENDING2, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
2008 { CH_XID7_PENDING2, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal },
2009 { CH_XID7_PENDING2, CTC_EVENT_TIMER, ctcmpc_chx_resend },
2010 { CH_XID7_PENDING2, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
2011
2012 { CH_XID7_PENDING3, CTC_EVENT_FINSTAT, ctcmpc_chx_rx },
2013 { CH_XID7_PENDING3, CTC_EVENT_ATTN, ctcmpc_chx_attn },
2014 { CH_XID7_PENDING3, CTC_EVENT_STOP, ctcm_chx_haltio },
2015 { CH_XID7_PENDING3, CTC_EVENT_START, ctcm_action_nop },
2016 { CH_XID7_PENDING3, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2017 { CH_XID7_PENDING3, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2018 { CH_XID7_PENDING3, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx },
2019 { CH_XID7_PENDING3, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
2020 { CH_XID7_PENDING3, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
2021 { CH_XID7_PENDING3, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal },
2022 { CH_XID7_PENDING3, CTC_EVENT_TIMER, ctcmpc_chx_resend },
2023 { CH_XID7_PENDING3, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
2024
2025 { CH_XID7_PENDING4, CTC_EVENT_FINSTAT, ctcmpc_chx_rx },
2026 { CH_XID7_PENDING4, CTC_EVENT_ATTN, ctcmpc_chx_attn },
2027 { CH_XID7_PENDING4, CTC_EVENT_STOP, ctcm_chx_haltio },
2028 { CH_XID7_PENDING4, CTC_EVENT_START, ctcm_action_nop },
2029 { CH_XID7_PENDING4, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2030 { CH_XID7_PENDING4, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2031 { CH_XID7_PENDING4, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx },
2032 { CH_XID7_PENDING4, CTC_EVENT_UC_RCRESET, ctcm_chx_setuperr },
2033 { CH_XID7_PENDING4, CTC_EVENT_UC_RSRESET, ctcm_chx_setuperr },
2034 { CH_XID7_PENDING4, CTC_EVENT_ATTNBUSY, ctcm_chx_iofatal },
2035 { CH_XID7_PENDING4, CTC_EVENT_TIMER, ctcmpc_chx_resend },
2036 { CH_XID7_PENDING4, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
2037
2038 { CTC_STATE_RXIDLE, CTC_EVENT_STOP, ctcm_chx_haltio },
2039 { CTC_STATE_RXIDLE, CTC_EVENT_START, ctcm_action_nop },
2040 { CTC_STATE_RXIDLE, CTC_EVENT_FINSTAT, ctcmpc_chx_rx },
2041 { CTC_STATE_RXIDLE, CTC_EVENT_UC_RCRESET, ctcm_chx_rxdisc },
2042 { CTC_STATE_RXIDLE, CTC_EVENT_UC_RSRESET, ctcm_chx_fail },
2043 { CTC_STATE_RXIDLE, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2044 { CTC_STATE_RXIDLE, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2045 { CTC_STATE_RXIDLE, CTC_EVENT_UC_ZERO, ctcmpc_chx_rx },
2046
2047 { CTC_STATE_TXINIT, CTC_EVENT_STOP, ctcm_chx_haltio },
2048 { CTC_STATE_TXINIT, CTC_EVENT_START, ctcm_action_nop },
2049 { CTC_STATE_TXINIT, CTC_EVENT_FINSTAT, ctcm_chx_txidle },
2050 { CTC_STATE_TXINIT, CTC_EVENT_UC_RCRESET, ctcm_chx_txiniterr },
2051 { CTC_STATE_TXINIT, CTC_EVENT_UC_RSRESET, ctcm_chx_txiniterr },
2052 { CTC_STATE_TXINIT, CTC_EVENT_TIMER, ctcm_chx_txiniterr },
2053 { CTC_STATE_TXINIT, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2054 { CTC_STATE_TXINIT, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2055 { CTC_STATE_TXINIT, CTC_EVENT_RSWEEP_TIMER, ctcmpc_chx_send_sweep },
2056
2057 { CTC_STATE_TXIDLE, CTC_EVENT_STOP, ctcm_chx_haltio },
2058 { CTC_STATE_TXIDLE, CTC_EVENT_START, ctcm_action_nop },
2059 { CTC_STATE_TXIDLE, CTC_EVENT_FINSTAT, ctcmpc_chx_firstio },
2060 { CTC_STATE_TXIDLE, CTC_EVENT_UC_RCRESET, ctcm_chx_fail },
2061 { CTC_STATE_TXIDLE, CTC_EVENT_UC_RSRESET, ctcm_chx_fail },
2062 { CTC_STATE_TXIDLE, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2063 { CTC_STATE_TXIDLE, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2064 { CTC_STATE_TXIDLE, CTC_EVENT_RSWEEP_TIMER, ctcmpc_chx_send_sweep },
2065
2066 { CTC_STATE_TERM, CTC_EVENT_STOP, ctcm_action_nop },
2067 { CTC_STATE_TERM, CTC_EVENT_START, ctcm_chx_restart },
2068 { CTC_STATE_TERM, CTC_EVENT_FINSTAT, ctcm_chx_stopped },
2069 { CTC_STATE_TERM, CTC_EVENT_UC_RCRESET, ctcm_action_nop },
2070 { CTC_STATE_TERM, CTC_EVENT_UC_RSRESET, ctcm_action_nop },
2071 { CTC_STATE_TERM, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2072 { CTC_STATE_TERM, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
2073 { CTC_STATE_TERM, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2074
2075 { CTC_STATE_DTERM, CTC_EVENT_STOP, ctcm_chx_haltio },
2076 { CTC_STATE_DTERM, CTC_EVENT_START, ctcm_chx_restart },
2077 { CTC_STATE_DTERM, CTC_EVENT_FINSTAT, ctcm_chx_setmode },
2078 { CTC_STATE_DTERM, CTC_EVENT_UC_RCRESET, ctcm_action_nop },
2079 { CTC_STATE_DTERM, CTC_EVENT_UC_RSRESET, ctcm_action_nop },
2080 { CTC_STATE_DTERM, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2081 { CTC_STATE_DTERM, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2082
2083 { CTC_STATE_TX, CTC_EVENT_STOP, ctcm_chx_haltio },
2084 { CTC_STATE_TX, CTC_EVENT_START, ctcm_action_nop },
2085 { CTC_STATE_TX, CTC_EVENT_FINSTAT, ctcmpc_chx_txdone },
2086 { CTC_STATE_TX, CTC_EVENT_UC_RCRESET, ctcm_chx_fail },
2087 { CTC_STATE_TX, CTC_EVENT_UC_RSRESET, ctcm_chx_fail },
2088 { CTC_STATE_TX, CTC_EVENT_TIMER, ctcm_chx_txretry },
2089 { CTC_STATE_TX, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2090 { CTC_STATE_TX, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2091 { CTC_STATE_TX, CTC_EVENT_RSWEEP_TIMER, ctcmpc_chx_send_sweep },
2092 { CTC_STATE_TX, CTC_EVENT_IO_EBUSY, ctcm_chx_fail },
2093
2094 { CTC_STATE_RXERR, CTC_EVENT_STOP, ctcm_chx_haltio },
2095 { CTC_STATE_TXERR, CTC_EVENT_STOP, ctcm_chx_haltio },
2096 { CTC_STATE_TXERR, CTC_EVENT_IO_ENODEV, ctcm_chx_iofatal },
2097 { CTC_STATE_TXERR, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2098 { CTC_STATE_RXERR, CTC_EVENT_MC_FAIL, ctcm_chx_fail },
2099};
2100
2101int mpc_ch_fsm_len = ARRAY_SIZE(ctcmpc_ch_fsm);
2102
2103/*
2104 * Actions for interface - statemachine.
2105 */
2106
2107/**
2108 * Startup channels by sending CTC_EVENT_START to each channel.
2109 *
2110 * fi An instance of an interface statemachine.
2111 * event The event, just happened.
2112 * arg Generic pointer, casted from struct net_device * upon call.
2113 */
2114static void dev_action_start(fsm_instance *fi, int event, void *arg)
2115{
2116 struct net_device *dev = arg;
2117 struct ctcm_priv *priv = dev->priv;
2118 int direction;
2119
2120 CTCMY_DBF_DEV_NAME(SETUP, dev, "");
2121
2122 fsm_deltimer(&priv->restart_timer);
2123 fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
2124 if (IS_MPC(priv))
2125 priv->mpcg->channels_terminating = 0;
2126 for (direction = READ; direction <= WRITE; direction++) {
2127 struct channel *ch = priv->channel[direction];
2128 fsm_event(ch->fsm, CTC_EVENT_START, ch);
2129 }
2130}
2131
2132/**
2133 * Shutdown channels by sending CTC_EVENT_STOP to each channel.
2134 *
2135 * fi An instance of an interface statemachine.
2136 * event The event, just happened.
2137 * arg Generic pointer, casted from struct net_device * upon call.
2138 */
2139static void dev_action_stop(fsm_instance *fi, int event, void *arg)
2140{
2141 int direction;
2142 struct net_device *dev = arg;
2143 struct ctcm_priv *priv = dev->priv;
2144
2145 CTCMY_DBF_DEV_NAME(SETUP, dev, "");
2146
2147 fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
2148 for (direction = READ; direction <= WRITE; direction++) {
2149 struct channel *ch = priv->channel[direction];
2150 fsm_event(ch->fsm, CTC_EVENT_STOP, ch);
2151 ch->th_seq_num = 0x00;
2152 if (do_debug)
2153 ctcm_pr_debug("ctcm: %s() CH_th_seq= %08x\n",
2154 __FUNCTION__, ch->th_seq_num);
2155 }
2156 if (IS_MPC(priv))
2157 fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET);
2158}
2159
2160static void dev_action_restart(fsm_instance *fi, int event, void *arg)
2161{
2162 int restart_timer;
2163 struct net_device *dev = arg;
2164 struct ctcm_priv *priv = dev->priv;
2165
2166 CTCMY_DBF_DEV_NAME(TRACE, dev, "");
2167
2168 if (IS_MPC(priv)) {
2169 ctcm_pr_info("ctcm: %s Restarting Device and "
2170 "MPC Group in 5 seconds\n",
2171 dev->name);
2172 restart_timer = CTCM_TIME_1_SEC;
2173 } else {
2174 ctcm_pr_info("%s: Restarting\n", dev->name);
2175 restart_timer = CTCM_TIME_5_SEC;
2176 }
2177
2178 dev_action_stop(fi, event, arg);
2179 fsm_event(priv->fsm, DEV_EVENT_STOP, dev);
2180 if (IS_MPC(priv))
2181 fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET);
2182
2183 /* going back into start sequence too quickly can */
2184 /* result in the other side becoming unreachable due */
2185 /* to sense reported when IO is aborted */
2186 fsm_addtimer(&priv->restart_timer, restart_timer,
2187 DEV_EVENT_START, dev);
2188}
2189
2190/**
2191 * Called from channel statemachine
2192 * when a channel is up and running.
2193 *
2194 * fi An instance of an interface statemachine.
2195 * event The event, just happened.
2196 * arg Generic pointer, casted from struct net_device * upon call.
2197 */
2198static void dev_action_chup(fsm_instance *fi, int event, void *arg)
2199{
2200 struct net_device *dev = arg;
2201 struct ctcm_priv *priv = dev->priv;
2202
2203 CTCMY_DBF_DEV_NAME(SETUP, dev, "");
2204
2205 switch (fsm_getstate(fi)) {
2206 case DEV_STATE_STARTWAIT_RXTX:
2207 if (event == DEV_EVENT_RXUP)
2208 fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
2209 else
2210 fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
2211 break;
2212 case DEV_STATE_STARTWAIT_RX:
2213 if (event == DEV_EVENT_RXUP) {
2214 fsm_newstate(fi, DEV_STATE_RUNNING);
2215 ctcm_pr_info("%s: connected with remote side\n",
2216 dev->name);
2217 ctcm_clear_busy(dev);
2218 }
2219 break;
2220 case DEV_STATE_STARTWAIT_TX:
2221 if (event == DEV_EVENT_TXUP) {
2222 fsm_newstate(fi, DEV_STATE_RUNNING);
2223 ctcm_pr_info("%s: connected with remote side\n",
2224 dev->name);
2225 ctcm_clear_busy(dev);
2226 }
2227 break;
2228 case DEV_STATE_STOPWAIT_TX:
2229 if (event == DEV_EVENT_RXUP)
2230 fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
2231 break;
2232 case DEV_STATE_STOPWAIT_RX:
2233 if (event == DEV_EVENT_TXUP)
2234 fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
2235 break;
2236 }
2237
2238 if (IS_MPC(priv)) {
2239 if (event == DEV_EVENT_RXUP)
2240 mpc_channel_action(priv->channel[READ],
2241 READ, MPC_CHANNEL_ADD);
2242 else
2243 mpc_channel_action(priv->channel[WRITE],
2244 WRITE, MPC_CHANNEL_ADD);
2245 }
2246}
2247
2248/**
2249 * Called from device statemachine
2250 * when a channel has been shutdown.
2251 *
2252 * fi An instance of an interface statemachine.
2253 * event The event, just happened.
2254 * arg Generic pointer, casted from struct net_device * upon call.
2255 */
2256static void dev_action_chdown(fsm_instance *fi, int event, void *arg)
2257{
2258
2259 struct net_device *dev = arg;
2260 struct ctcm_priv *priv = dev->priv;
2261
2262 CTCMY_DBF_DEV_NAME(SETUP, dev, "");
2263
2264 switch (fsm_getstate(fi)) {
2265 case DEV_STATE_RUNNING:
2266 if (event == DEV_EVENT_TXDOWN)
2267 fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
2268 else
2269 fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
2270 break;
2271 case DEV_STATE_STARTWAIT_RX:
2272 if (event == DEV_EVENT_TXDOWN)
2273 fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
2274 break;
2275 case DEV_STATE_STARTWAIT_TX:
2276 if (event == DEV_EVENT_RXDOWN)
2277 fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
2278 break;
2279 case DEV_STATE_STOPWAIT_RXTX:
2280 if (event == DEV_EVENT_TXDOWN)
2281 fsm_newstate(fi, DEV_STATE_STOPWAIT_RX);
2282 else
2283 fsm_newstate(fi, DEV_STATE_STOPWAIT_TX);
2284 break;
2285 case DEV_STATE_STOPWAIT_RX:
2286 if (event == DEV_EVENT_RXDOWN)
2287 fsm_newstate(fi, DEV_STATE_STOPPED);
2288 break;
2289 case DEV_STATE_STOPWAIT_TX:
2290 if (event == DEV_EVENT_TXDOWN)
2291 fsm_newstate(fi, DEV_STATE_STOPPED);
2292 break;
2293 }
2294 if (IS_MPC(priv)) {
2295 if (event == DEV_EVENT_RXDOWN)
2296 mpc_channel_action(priv->channel[READ],
2297 READ, MPC_CHANNEL_REMOVE);
2298 else
2299 mpc_channel_action(priv->channel[WRITE],
2300 WRITE, MPC_CHANNEL_REMOVE);
2301 }
2302}
2303
2304const fsm_node dev_fsm[] = {
2305 { DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start },
2306 { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_START, dev_action_start },
2307 { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown },
2308 { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown },
2309 { DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },
2310 { DEV_STATE_STOPWAIT_RX, DEV_EVENT_START, dev_action_start },
2311 { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXUP, dev_action_chup },
2312 { DEV_STATE_STOPWAIT_RX, DEV_EVENT_TXUP, dev_action_chup },
2313 { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXDOWN, dev_action_chdown },
2314 { DEV_STATE_STOPWAIT_RX, DEV_EVENT_RESTART, dev_action_restart },
2315 { DEV_STATE_STOPWAIT_TX, DEV_EVENT_START, dev_action_start },
2316 { DEV_STATE_STOPWAIT_TX, DEV_EVENT_RXUP, dev_action_chup },
2317 { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXUP, dev_action_chup },
2318 { DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXDOWN, dev_action_chdown },
2319 { DEV_STATE_STOPWAIT_TX, DEV_EVENT_RESTART, dev_action_restart },
2320 { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP, dev_action_stop },
2321 { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP, dev_action_chup },
2322 { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP, dev_action_chup },
2323 { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown },
2324 { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown },
2325 { DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },
2326 { DEV_STATE_STARTWAIT_TX, DEV_EVENT_STOP, dev_action_stop },
2327 { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXUP, dev_action_chup },
2328 { DEV_STATE_STARTWAIT_TX, DEV_EVENT_TXUP, dev_action_chup },
2329 { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXDOWN, dev_action_chdown },
2330 { DEV_STATE_STARTWAIT_TX, DEV_EVENT_RESTART, dev_action_restart },
2331 { DEV_STATE_STARTWAIT_RX, DEV_EVENT_STOP, dev_action_stop },
2332 { DEV_STATE_STARTWAIT_RX, DEV_EVENT_RXUP, dev_action_chup },
2333 { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXUP, dev_action_chup },
2334 { DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXDOWN, dev_action_chdown },
2335 { DEV_STATE_STARTWAIT_RX, DEV_EVENT_RESTART, dev_action_restart },
2336 { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop },
2337 { DEV_STATE_RUNNING, DEV_EVENT_RXDOWN, dev_action_chdown },
2338 { DEV_STATE_RUNNING, DEV_EVENT_TXDOWN, dev_action_chdown },
2339 { DEV_STATE_RUNNING, DEV_EVENT_TXUP, ctcm_action_nop },
2340 { DEV_STATE_RUNNING, DEV_EVENT_RXUP, ctcm_action_nop },
2341 { DEV_STATE_RUNNING, DEV_EVENT_RESTART, dev_action_restart },
2342};
2343
2344int dev_fsm_len = ARRAY_SIZE(dev_fsm);
2345
2346/* --- This is the END my friend --- */
2347
diff --git a/drivers/s390/net/ctcm_fsms.h b/drivers/s390/net/ctcm_fsms.h
new file mode 100644
index 000000000000..2326aba9807a
--- /dev/null
+++ b/drivers/s390/net/ctcm_fsms.h
@@ -0,0 +1,359 @@
1/*
2 * drivers/s390/net/ctcm_fsms.h
3 *
4 * Copyright IBM Corp. 2001, 2007
5 * Authors: Fritz Elfert (felfert@millenux.com)
6 * Peter Tiedemann (ptiedem@de.ibm.com)
7 * MPC additions :
8 * Belinda Thompson (belindat@us.ibm.com)
9 * Andy Richter (richtera@us.ibm.com)
10 */
11#ifndef _CTCM_FSMS_H_
12#define _CTCM_FSMS_H_
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/slab.h>
18#include <linux/errno.h>
19#include <linux/types.h>
20#include <linux/interrupt.h>
21#include <linux/timer.h>
22#include <linux/bitops.h>
23
24#include <linux/signal.h>
25#include <linux/string.h>
26
27#include <linux/ip.h>
28#include <linux/if_arp.h>
29#include <linux/tcp.h>
30#include <linux/skbuff.h>
31#include <linux/ctype.h>
32#include <net/dst.h>
33
34#include <linux/io.h>
35#include <asm/ccwdev.h>
36#include <asm/ccwgroup.h>
37#include <linux/uaccess.h>
38
39#include <asm/idals.h>
40
41#include "fsm.h"
42#include "cu3088.h"
43#include "ctcm_main.h"
44
45/*
46 * Definitions for the channel statemachine(s) for ctc and ctcmpc
47 *
48 * To allow better kerntyping, prefix-less definitions for channel states
49 * and channel events have been replaced :
50 * ch_event... -> ctc_ch_event...
51 * CH_EVENT... -> CTC_EVENT...
52 * ch_state... -> ctc_ch_state...
53 * CH_STATE... -> CTC_STATE...
54 */
55/*
56 * Events of the channel statemachine(s) for ctc and ctcmpc
57 */
58enum ctc_ch_events {
59 /*
60 * Events, representing return code of
61 * I/O operations (ccw_device_start, ccw_device_halt et al.)
62 */
63 CTC_EVENT_IO_SUCCESS,
64 CTC_EVENT_IO_EBUSY,
65 CTC_EVENT_IO_ENODEV,
66 CTC_EVENT_IO_UNKNOWN,
67
68 CTC_EVENT_ATTNBUSY,
69 CTC_EVENT_ATTN,
70 CTC_EVENT_BUSY,
71 /*
72 * Events, representing unit-check
73 */
74 CTC_EVENT_UC_RCRESET,
75 CTC_EVENT_UC_RSRESET,
76 CTC_EVENT_UC_TXTIMEOUT,
77 CTC_EVENT_UC_TXPARITY,
78 CTC_EVENT_UC_HWFAIL,
79 CTC_EVENT_UC_RXPARITY,
80 CTC_EVENT_UC_ZERO,
81 CTC_EVENT_UC_UNKNOWN,
82 /*
83 * Events, representing subchannel-check
84 */
85 CTC_EVENT_SC_UNKNOWN,
86 /*
87 * Events, representing machine checks
88 */
89 CTC_EVENT_MC_FAIL,
90 CTC_EVENT_MC_GOOD,
91 /*
92 * Event, representing normal IRQ
93 */
94 CTC_EVENT_IRQ,
95 CTC_EVENT_FINSTAT,
96 /*
97 * Event, representing timer expiry.
98 */
99 CTC_EVENT_TIMER,
100 /*
101 * Events, representing commands from upper levels.
102 */
103 CTC_EVENT_START,
104 CTC_EVENT_STOP,
105 CTC_NR_EVENTS,
106 /*
107 * additional MPC events
108 */
109 CTC_EVENT_SEND_XID = CTC_NR_EVENTS,
110 CTC_EVENT_RSWEEP_TIMER,
111 /*
112 * MUST be always the last element!!
113 */
114 CTC_MPC_NR_EVENTS,
115};
116
117/*
118 * States of the channel statemachine(s) for ctc and ctcmpc.
119 */
120enum ctc_ch_states {
121 /*
122 * Channel not assigned to any device,
123 * initial state, direction invalid
124 */
125 CTC_STATE_IDLE,
126 /*
127 * Channel assigned but not operating
128 */
129 CTC_STATE_STOPPED,
130 CTC_STATE_STARTWAIT,
131 CTC_STATE_STARTRETRY,
132 CTC_STATE_SETUPWAIT,
133 CTC_STATE_RXINIT,
134 CTC_STATE_TXINIT,
135 CTC_STATE_RX,
136 CTC_STATE_TX,
137 CTC_STATE_RXIDLE,
138 CTC_STATE_TXIDLE,
139 CTC_STATE_RXERR,
140 CTC_STATE_TXERR,
141 CTC_STATE_TERM,
142 CTC_STATE_DTERM,
143 CTC_STATE_NOTOP,
144 CTC_NR_STATES, /* MUST be the last element of non-expanded states */
145 /*
146 * additional MPC states
147 */
148 CH_XID0_PENDING = CTC_NR_STATES,
149 CH_XID0_INPROGRESS,
150 CH_XID7_PENDING,
151 CH_XID7_PENDING1,
152 CH_XID7_PENDING2,
153 CH_XID7_PENDING3,
154 CH_XID7_PENDING4,
155 CTC_MPC_NR_STATES, /* MUST be the last element of expanded mpc states */
156};
157
158extern const char *ctc_ch_event_names[];
159
160extern const char *ctc_ch_state_names[];
161
162void ctcm_ccw_check_rc(struct channel *ch, int rc, char *msg);
163void ctcm_purge_skb_queue(struct sk_buff_head *q);
164void fsm_action_nop(fsm_instance *fi, int event, void *arg);
165
166/*
167 * ----- non-static actions for ctcm channel statemachine -----
168 *
169 */
170void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg);
171
172/*
173 * ----- FSM (state/event/action) of the ctcm channel statemachine -----
174 */
175extern const fsm_node ch_fsm[];
176extern int ch_fsm_len;
177
178
179/*
180 * ----- non-static actions for ctcmpc channel statemachine ----
181 *
182 */
183/* shared :
184void ctcm_chx_txidle(fsm_instance * fi, int event, void *arg);
185 */
186void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg);
187
188/*
189 * ----- FSM (state/event/action) of the ctcmpc channel statemachine -----
190 */
191extern const fsm_node ctcmpc_ch_fsm[];
192extern int mpc_ch_fsm_len;
193
194/*
195 * Definitions for the device interface statemachine for ctc and mpc
196 */
197
198/*
199 * States of the device interface statemachine.
200 */
201enum dev_states {
202 DEV_STATE_STOPPED,
203 DEV_STATE_STARTWAIT_RXTX,
204 DEV_STATE_STARTWAIT_RX,
205 DEV_STATE_STARTWAIT_TX,
206 DEV_STATE_STOPWAIT_RXTX,
207 DEV_STATE_STOPWAIT_RX,
208 DEV_STATE_STOPWAIT_TX,
209 DEV_STATE_RUNNING,
210 /*
211 * MUST be always the last element!!
212 */
213 CTCM_NR_DEV_STATES
214};
215
216extern const char *dev_state_names[];
217
218/*
219 * Events of the device interface statemachine.
220 * ctcm and ctcmpc
221 */
222enum dev_events {
223 DEV_EVENT_START,
224 DEV_EVENT_STOP,
225 DEV_EVENT_RXUP,
226 DEV_EVENT_TXUP,
227 DEV_EVENT_RXDOWN,
228 DEV_EVENT_TXDOWN,
229 DEV_EVENT_RESTART,
230 /*
231 * MUST be always the last element!!
232 */
233 CTCM_NR_DEV_EVENTS
234};
235
236extern const char *dev_event_names[];
237
238/*
239 * Actions for the device interface statemachine.
240 * ctc and ctcmpc
241 */
242/*
243static void dev_action_start(fsm_instance * fi, int event, void *arg);
244static void dev_action_stop(fsm_instance * fi, int event, void *arg);
245static void dev_action_restart(fsm_instance *fi, int event, void *arg);
246static void dev_action_chup(fsm_instance * fi, int event, void *arg);
247static void dev_action_chdown(fsm_instance * fi, int event, void *arg);
248*/
249
250/*
251 * The (state/event/action) fsm table of the device interface statemachine.
252 * ctcm and ctcmpc
253 */
254extern const fsm_node dev_fsm[];
255extern int dev_fsm_len;
256
257
258/*
259 * Definitions for the MPC Group statemachine
260 */
261
262/*
263 * MPC Group Station FSM States
264
265State Name When In This State
266====================== =======================================
267MPCG_STATE_RESET Initial State When Driver Loaded
268 We receive and send NOTHING
269
270MPCG_STATE_INOP INOP Received.
271 Group level non-recoverable error
272
273MPCG_STATE_READY XID exchanges for at least 1 write and
274 1 read channel have completed.
275 Group is ready for data transfer.
276
277States from ctc_mpc_alloc_channel
278==============================================================
279MPCG_STATE_XID2INITW Awaiting XID2(0) Initiation
280 ATTN from other side will start
281 XID negotiations.
282 Y-side protocol only.
283
284MPCG_STATE_XID2INITX XID2(0) negotiations are in progress.
285 At least 1, but not all, XID2(0)'s
286 have been received from partner.
287
288MPCG_STATE_XID7INITW XID2(0) complete
289 No XID2(7)'s have yet been received.
290 XID2(7) negotiations pending.
291
292MPCG_STATE_XID7INITX XID2(7) negotiations in progress.
293 At least 1, but not all, XID2(7)'s
294 have been received from partner.
295
296MPCG_STATE_XID7INITF XID2(7) negotiations complete.
297 Transitioning to READY.
298
299MPCG_STATE_READY Ready for Data Transfer.
300
301
302States from ctc_mpc_establish_connectivity call
303==============================================================
304MPCG_STATE_XID0IOWAIT Initiating XID2(0) negotiations.
305 X-side protocol only.
306 ATTN-BUSY from other side will convert
307 this to Y-side protocol and the
308 ctc_mpc_alloc_channel flow will begin.
309
310MPCG_STATE_XID0IOWAIX XID2(0) negotiations are in progress.
311 At least 1, but not all, XID2(0)'s
312 have been received from partner.
313
314MPCG_STATE_XID7INITI XID2(0) complete
315 No XID2(7)'s have yet been received.
316 XID2(7) negotiations pending.
317
318MPCG_STATE_XID7INITZ XID2(7) negotiations in progress.
319 At least 1, but not all, XID2(7)'s
320 have been received from partner.
321
322MPCG_STATE_XID7INITF XID2(7) negotiations complete.
323 Transitioning to READY.
324
325MPCG_STATE_READY Ready for Data Transfer.
326
327*/
328
329enum mpcg_events {
330 MPCG_EVENT_INOP,
331 MPCG_EVENT_DISCONC,
332 MPCG_EVENT_XID0DO,
333 MPCG_EVENT_XID2,
334 MPCG_EVENT_XID2DONE,
335 MPCG_EVENT_XID7DONE,
336 MPCG_EVENT_TIMER,
337 MPCG_EVENT_DOIO,
338 MPCG_NR_EVENTS,
339};
340
341enum mpcg_states {
342 MPCG_STATE_RESET,
343 MPCG_STATE_INOP,
344 MPCG_STATE_XID2INITW,
345 MPCG_STATE_XID2INITX,
346 MPCG_STATE_XID7INITW,
347 MPCG_STATE_XID7INITX,
348 MPCG_STATE_XID0IOWAIT,
349 MPCG_STATE_XID0IOWAIX,
350 MPCG_STATE_XID7INITI,
351 MPCG_STATE_XID7INITZ,
352 MPCG_STATE_XID7INITF,
353 MPCG_STATE_FLOWC,
354 MPCG_STATE_READY,
355 MPCG_NR_STATES,
356};
357
358#endif
359/* --- This is the END my friend --- */
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
new file mode 100644
index 000000000000..d52843da4f55
--- /dev/null
+++ b/drivers/s390/net/ctcm_main.c
@@ -0,0 +1,1772 @@
1/*
2 * drivers/s390/net/ctcm_main.c
3 *
4 * Copyright IBM Corp. 2001, 2007
5 * Author(s):
6 * Original CTC driver(s):
7 * Fritz Elfert (felfert@millenux.com)
8 * Dieter Wellerdiek (wel@de.ibm.com)
9 * Martin Schwidefsky (schwidefsky@de.ibm.com)
10 * Denis Joseph Barrow (barrow_dj@yahoo.com)
11 * Jochen Roehrig (roehrig@de.ibm.com)
12 * Cornelia Huck <cornelia.huck@de.ibm.com>
13 * MPC additions:
14 * Belinda Thompson (belindat@us.ibm.com)
15 * Andy Richter (richtera@us.ibm.com)
16 * Revived by:
17 * Peter Tiedemann (ptiedem@de.ibm.com)
18 */
19
20#undef DEBUG
21#undef DEBUGDATA
22#undef DEBUGCCW
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/errno.h>
29#include <linux/types.h>
30#include <linux/interrupt.h>
31#include <linux/timer.h>
32#include <linux/bitops.h>
33
34#include <linux/signal.h>
35#include <linux/string.h>
36
37#include <linux/ip.h>
38#include <linux/if_arp.h>
39#include <linux/tcp.h>
40#include <linux/skbuff.h>
41#include <linux/ctype.h>
42#include <net/dst.h>
43
44#include <linux/io.h>
45#include <asm/ccwdev.h>
46#include <asm/ccwgroup.h>
47#include <linux/uaccess.h>
48
49#include <asm/idals.h>
50
51#include "cu3088.h"
52#include "ctcm_fsms.h"
53#include "ctcm_main.h"
54
55/* Some common global variables */
56
57/*
58 * Linked list of all detected channels.
59 */
60struct channel *channels;
61
62/**
63 * Unpack a just received skb and hand it over to
64 * upper layers.
65 *
66 * ch The channel where this skb has been received.
67 * pskb The received skb.
68 */
69void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
70{
71 struct net_device *dev = ch->netdev;
72 struct ctcm_priv *priv = dev->priv;
73 __u16 len = *((__u16 *) pskb->data);
74
75 skb_put(pskb, 2 + LL_HEADER_LENGTH);
76 skb_pull(pskb, 2);
77 pskb->dev = dev;
78 pskb->ip_summed = CHECKSUM_UNNECESSARY;
79 while (len > 0) {
80 struct sk_buff *skb;
81 int skblen;
82 struct ll_header *header = (struct ll_header *)pskb->data;
83
84 skb_pull(pskb, LL_HEADER_LENGTH);
85 if ((ch->protocol == CTCM_PROTO_S390) &&
86 (header->type != ETH_P_IP)) {
87
88 if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) {
89 /*
90 * Check packet type only if we stick strictly
91 * to S/390's protocol of OS390. This only
92 * supports IP. Otherwise allow any packet
93 * type.
94 */
95 ctcm_pr_warn("%s Illegal packet type 0x%04x "
96 "received, dropping\n",
97 dev->name, header->type);
98 ch->logflags |= LOG_FLAG_ILLEGALPKT;
99 }
100
101 priv->stats.rx_dropped++;
102 priv->stats.rx_frame_errors++;
103 return;
104 }
105 pskb->protocol = ntohs(header->type);
106 if (header->length <= LL_HEADER_LENGTH) {
107 if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
108 ctcm_pr_warn(
109 "%s Illegal packet size %d "
110 "received (MTU=%d blocklen=%d), "
111 "dropping\n", dev->name, header->length,
112 dev->mtu, len);
113 ch->logflags |= LOG_FLAG_ILLEGALSIZE;
114 }
115
116 priv->stats.rx_dropped++;
117 priv->stats.rx_length_errors++;
118 return;
119 }
120 header->length -= LL_HEADER_LENGTH;
121 len -= LL_HEADER_LENGTH;
122 if ((header->length > skb_tailroom(pskb)) ||
123 (header->length > len)) {
124 if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
125 ctcm_pr_warn(
126 "%s Illegal packet size %d (beyond the"
127 " end of received data), dropping\n",
128 dev->name, header->length);
129 ch->logflags |= LOG_FLAG_OVERRUN;
130 }
131
132 priv->stats.rx_dropped++;
133 priv->stats.rx_length_errors++;
134 return;
135 }
136 skb_put(pskb, header->length);
137 skb_reset_mac_header(pskb);
138 len -= header->length;
139 skb = dev_alloc_skb(pskb->len);
140 if (!skb) {
141 if (!(ch->logflags & LOG_FLAG_NOMEM)) {
142 ctcm_pr_warn(
143 "%s Out of memory in ctcm_unpack_skb\n",
144 dev->name);
145 ch->logflags |= LOG_FLAG_NOMEM;
146 }
147 priv->stats.rx_dropped++;
148 return;
149 }
150 skb_copy_from_linear_data(pskb, skb_put(skb, pskb->len),
151 pskb->len);
152 skb_reset_mac_header(skb);
153 skb->dev = pskb->dev;
154 skb->protocol = pskb->protocol;
155 pskb->ip_summed = CHECKSUM_UNNECESSARY;
156 skblen = skb->len;
157 /*
158 * reset logflags
159 */
160 ch->logflags = 0;
161 priv->stats.rx_packets++;
162 priv->stats.rx_bytes += skblen;
163 netif_rx_ni(skb);
164 dev->last_rx = jiffies;
165 if (len > 0) {
166 skb_pull(pskb, header->length);
167 if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
168 if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
169 CTCM_DBF_DEV_NAME(TRACE, dev,
170 "Overrun in ctcm_unpack_skb");
171 ch->logflags |= LOG_FLAG_OVERRUN;
172 }
173 return;
174 }
175 skb_put(pskb, LL_HEADER_LENGTH);
176 }
177 }
178}
179
180/**
181 * Release a specific channel in the channel list.
182 *
183 * ch Pointer to channel struct to be released.
184 */
185static void channel_free(struct channel *ch)
186{
187 CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
188 ch->flags &= ~CHANNEL_FLAGS_INUSE;
189 fsm_newstate(ch->fsm, CTC_STATE_IDLE);
190}
191
192/**
193 * Remove a specific channel in the channel list.
194 *
195 * ch Pointer to channel struct to be released.
196 */
197static void channel_remove(struct channel *ch)
198{
199 struct channel **c = &channels;
200 char chid[CTCM_ID_SIZE+1];
201 int ok = 0;
202
203 if (ch == NULL)
204 return;
205 else
206 strncpy(chid, ch->id, CTCM_ID_SIZE);
207
208 channel_free(ch);
209 while (*c) {
210 if (*c == ch) {
211 *c = ch->next;
212 fsm_deltimer(&ch->timer);
213 if (IS_MPC(ch))
214 fsm_deltimer(&ch->sweep_timer);
215
216 kfree_fsm(ch->fsm);
217 clear_normalized_cda(&ch->ccw[4]);
218 if (ch->trans_skb != NULL) {
219 clear_normalized_cda(&ch->ccw[1]);
220 dev_kfree_skb_any(ch->trans_skb);
221 }
222 if (IS_MPC(ch)) {
223 tasklet_kill(&ch->ch_tasklet);
224 tasklet_kill(&ch->ch_disc_tasklet);
225 kfree(ch->discontact_th);
226 }
227 kfree(ch->ccw);
228 kfree(ch->irb);
229 kfree(ch);
230 ok = 1;
231 break;
232 }
233 c = &((*c)->next);
234 }
235
236 CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s) %s", CTCM_FUNTAIL,
237 chid, ok ? "OK" : "failed");
238}
239
240/**
241 * Get a specific channel from the channel list.
242 *
243 * type Type of channel we are interested in.
244 * id Id of channel we are interested in.
245 * direction Direction we want to use this channel for.
246 *
247 * returns Pointer to a channel or NULL if no matching channel available.
248 */
249static struct channel *channel_get(enum channel_types type,
250 char *id, int direction)
251{
252 struct channel *ch = channels;
253
254 if (do_debug) {
255 char buf[64];
256 sprintf(buf, "%s(%d, %s, %d)\n",
257 CTCM_FUNTAIL, type, id, direction);
258 CTCM_DBF_TEXT(TRACE, CTC_DBF_INFO, buf);
259 }
260 while (ch && (strncmp(ch->id, id, CTCM_ID_SIZE) || (ch->type != type)))
261 ch = ch->next;
262 if (!ch) {
263 char buf[64];
264 sprintf(buf, "%s(%d, %s, %d) not found in channel list\n",
265 CTCM_FUNTAIL, type, id, direction);
266 CTCM_DBF_TEXT(ERROR, CTC_DBF_ERROR, buf);
267 } else {
268 if (ch->flags & CHANNEL_FLAGS_INUSE)
269 ch = NULL;
270 else {
271 ch->flags |= CHANNEL_FLAGS_INUSE;
272 ch->flags &= ~CHANNEL_FLAGS_RWMASK;
273 ch->flags |= (direction == WRITE)
274 ? CHANNEL_FLAGS_WRITE : CHANNEL_FLAGS_READ;
275 fsm_newstate(ch->fsm, CTC_STATE_STOPPED);
276 }
277 }
278 return ch;
279}
280
281static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb)
282{
283 if (!IS_ERR(irb))
284 return 0;
285
286 CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN, "irb error %ld on device %s\n",
287 PTR_ERR(irb), cdev->dev.bus_id);
288
289 switch (PTR_ERR(irb)) {
290 case -EIO:
291 ctcm_pr_warn("i/o-error on device %s\n", cdev->dev.bus_id);
292 break;
293 case -ETIMEDOUT:
294 ctcm_pr_warn("timeout on device %s\n", cdev->dev.bus_id);
295 break;
296 default:
297 ctcm_pr_warn("unknown error %ld on device %s\n",
298 PTR_ERR(irb), cdev->dev.bus_id);
299 }
300 return PTR_ERR(irb);
301}
302
303
304/**
305 * Check sense of a unit check.
306 *
307 * ch The channel, the sense code belongs to.
308 * sense The sense code to inspect.
309 */
310static inline void ccw_unit_check(struct channel *ch, unsigned char sense)
311{
312 CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
313 if (sense & SNS0_INTERVENTION_REQ) {
314 if (sense & 0x01) {
315 ctcm_pr_debug("%s: Interface disc. or Sel. reset "
316 "(remote)\n", ch->id);
317 fsm_event(ch->fsm, CTC_EVENT_UC_RCRESET, ch);
318 } else {
319 ctcm_pr_debug("%s: System reset (remote)\n", ch->id);
320 fsm_event(ch->fsm, CTC_EVENT_UC_RSRESET, ch);
321 }
322 } else if (sense & SNS0_EQUIPMENT_CHECK) {
323 if (sense & SNS0_BUS_OUT_CHECK) {
324 ctcm_pr_warn("%s: Hardware malfunction (remote)\n",
325 ch->id);
326 fsm_event(ch->fsm, CTC_EVENT_UC_HWFAIL, ch);
327 } else {
328 ctcm_pr_warn("%s: Read-data parity error (remote)\n",
329 ch->id);
330 fsm_event(ch->fsm, CTC_EVENT_UC_RXPARITY, ch);
331 }
332 } else if (sense & SNS0_BUS_OUT_CHECK) {
333 if (sense & 0x04) {
334 ctcm_pr_warn("%s: Data-streaming timeout)\n", ch->id);
335 fsm_event(ch->fsm, CTC_EVENT_UC_TXTIMEOUT, ch);
336 } else {
337 ctcm_pr_warn("%s: Data-transfer parity error\n",
338 ch->id);
339 fsm_event(ch->fsm, CTC_EVENT_UC_TXPARITY, ch);
340 }
341 } else if (sense & SNS0_CMD_REJECT) {
342 ctcm_pr_warn("%s: Command reject\n", ch->id);
343 } else if (sense == 0) {
344 ctcm_pr_debug("%s: Unit check ZERO\n", ch->id);
345 fsm_event(ch->fsm, CTC_EVENT_UC_ZERO, ch);
346 } else {
347 ctcm_pr_warn("%s: Unit Check with sense code: %02x\n",
348 ch->id, sense);
349 fsm_event(ch->fsm, CTC_EVENT_UC_UNKNOWN, ch);
350 }
351}
352
353int ctcm_ch_alloc_buffer(struct channel *ch)
354{
355 CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
356
357 clear_normalized_cda(&ch->ccw[1]);
358 ch->trans_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC | GFP_DMA);
359 if (ch->trans_skb == NULL) {
360 ctcm_pr_warn("%s: Couldn't alloc %s trans_skb\n",
361 ch->id,
362 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
363 return -ENOMEM;
364 }
365
366 ch->ccw[1].count = ch->max_bufsize;
367 if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
368 dev_kfree_skb(ch->trans_skb);
369 ch->trans_skb = NULL;
370 ctcm_pr_warn("%s: set_normalized_cda for %s "
371 "trans_skb failed, dropping packets\n",
372 ch->id,
373 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
374 return -ENOMEM;
375 }
376
377 ch->ccw[1].count = 0;
378 ch->trans_skb_data = ch->trans_skb->data;
379 ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED;
380 return 0;
381}
382
383/*
384 * Interface API for upper network layers
385 */
386
387/**
388 * Open an interface.
389 * Called from generic network layer when ifconfig up is run.
390 *
391 * dev Pointer to interface struct.
392 *
393 * returns 0 on success, -ERRNO on failure. (Never fails.)
394 */
395int ctcm_open(struct net_device *dev)
396{
397 struct ctcm_priv *priv = dev->priv;
398
399 CTCMY_DBF_DEV_NAME(SETUP, dev, "");
400 if (!IS_MPC(priv))
401 fsm_event(priv->fsm, DEV_EVENT_START, dev);
402 return 0;
403}
404
405/**
406 * Close an interface.
407 * Called from generic network layer when ifconfig down is run.
408 *
409 * dev Pointer to interface struct.
410 *
411 * returns 0 on success, -ERRNO on failure. (Never fails.)
412 */
413int ctcm_close(struct net_device *dev)
414{
415 struct ctcm_priv *priv = dev->priv;
416
417 CTCMY_DBF_DEV_NAME(SETUP, dev, "");
418 if (!IS_MPC(priv))
419 fsm_event(priv->fsm, DEV_EVENT_STOP, dev);
420 return 0;
421}
422
423
424/**
425 * Transmit a packet.
426 * This is a helper function for ctcm_tx().
427 *
428 * ch Channel to be used for sending.
429 * skb Pointer to struct sk_buff of packet to send.
430 * The linklevel header has already been set up
431 * by ctcm_tx().
432 *
433 * returns 0 on success, -ERRNO on failure. (Never fails.)
434 */
435static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
436{
437 unsigned long saveflags;
438 struct ll_header header;
439 int rc = 0;
440 __u16 block_len;
441 int ccw_idx;
442 struct sk_buff *nskb;
443 unsigned long hi;
444
445 /* we need to acquire the lock for testing the state
446 * otherwise we can have an IRQ changing the state to
447 * TXIDLE after the test but before acquiring the lock.
448 */
449 spin_lock_irqsave(&ch->collect_lock, saveflags);
450 if (fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) {
451 int l = skb->len + LL_HEADER_LENGTH;
452
453 if (ch->collect_len + l > ch->max_bufsize - 2) {
454 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
455 return -EBUSY;
456 } else {
457 atomic_inc(&skb->users);
458 header.length = l;
459 header.type = skb->protocol;
460 header.unused = 0;
461 memcpy(skb_push(skb, LL_HEADER_LENGTH), &header,
462 LL_HEADER_LENGTH);
463 skb_queue_tail(&ch->collect_queue, skb);
464 ch->collect_len += l;
465 }
466 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
467 goto done;
468 }
469 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
470 /*
471 * Protect skb against beeing free'd by upper
472 * layers.
473 */
474 atomic_inc(&skb->users);
475 ch->prof.txlen += skb->len;
476 header.length = skb->len + LL_HEADER_LENGTH;
477 header.type = skb->protocol;
478 header.unused = 0;
479 memcpy(skb_push(skb, LL_HEADER_LENGTH), &header, LL_HEADER_LENGTH);
480 block_len = skb->len + 2;
481 *((__u16 *)skb_push(skb, 2)) = block_len;
482
483 /*
484 * IDAL support in CTCM is broken, so we have to
485 * care about skb's above 2G ourselves.
486 */
487 hi = ((unsigned long)skb_tail_pointer(skb) + LL_HEADER_LENGTH) >> 31;
488 if (hi) {
489 nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
490 if (!nskb) {
491 atomic_dec(&skb->users);
492 skb_pull(skb, LL_HEADER_LENGTH + 2);
493 ctcm_clear_busy(ch->netdev);
494 return -ENOMEM;
495 } else {
496 memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
497 atomic_inc(&nskb->users);
498 atomic_dec(&skb->users);
499 dev_kfree_skb_irq(skb);
500 skb = nskb;
501 }
502 }
503
504 ch->ccw[4].count = block_len;
505 if (set_normalized_cda(&ch->ccw[4], skb->data)) {
506 /*
507 * idal allocation failed, try via copying to
508 * trans_skb. trans_skb usually has a pre-allocated
509 * idal.
510 */
511 if (ctcm_checkalloc_buffer(ch)) {
512 /*
513 * Remove our header. It gets added
514 * again on retransmit.
515 */
516 atomic_dec(&skb->users);
517 skb_pull(skb, LL_HEADER_LENGTH + 2);
518 ctcm_clear_busy(ch->netdev);
519 return -EBUSY;
520 }
521
522 skb_reset_tail_pointer(ch->trans_skb);
523 ch->trans_skb->len = 0;
524 ch->ccw[1].count = skb->len;
525 skb_copy_from_linear_data(skb,
526 skb_put(ch->trans_skb, skb->len), skb->len);
527 atomic_dec(&skb->users);
528 dev_kfree_skb_irq(skb);
529 ccw_idx = 0;
530 } else {
531 skb_queue_tail(&ch->io_queue, skb);
532 ccw_idx = 3;
533 }
534 ch->retry = 0;
535 fsm_newstate(ch->fsm, CTC_STATE_TX);
536 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
537 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
538 ch->prof.send_stamp = current_kernel_time(); /* xtime */
539 rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx],
540 (unsigned long)ch, 0xff, 0);
541 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
542 if (ccw_idx == 3)
543 ch->prof.doios_single++;
544 if (rc != 0) {
545 fsm_deltimer(&ch->timer);
546 ctcm_ccw_check_rc(ch, rc, "single skb TX");
547 if (ccw_idx == 3)
548 skb_dequeue_tail(&ch->io_queue);
549 /*
550 * Remove our header. It gets added
551 * again on retransmit.
552 */
553 skb_pull(skb, LL_HEADER_LENGTH + 2);
554 } else if (ccw_idx == 0) {
555 struct net_device *dev = ch->netdev;
556 struct ctcm_priv *priv = dev->priv;
557 priv->stats.tx_packets++;
558 priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
559 }
560done:
561 ctcm_clear_busy(ch->netdev);
562 return rc;
563}
564
565static void ctcmpc_send_sweep_req(struct channel *rch)
566{
567 struct net_device *dev = rch->netdev;
568 struct ctcm_priv *priv;
569 struct mpc_group *grp;
570 struct th_sweep *header;
571 struct sk_buff *sweep_skb;
572 struct channel *ch;
573 int rc = 0;
574
575 priv = dev->priv;
576 grp = priv->mpcg;
577 ch = priv->channel[WRITE];
578
579 if (do_debug)
580 MPC_DBF_DEV_NAME(TRACE, dev, ch->id);
581
582 /* sweep processing is not complete until response and request */
583 /* has completed for all read channels in group */
584 if (grp->in_sweep == 0) {
585 grp->in_sweep = 1;
586 grp->sweep_rsp_pend_num = grp->active_channels[READ];
587 grp->sweep_req_pend_num = grp->active_channels[READ];
588 }
589
590 sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);
591
592 if (sweep_skb == NULL) {
593 printk(KERN_INFO "Couldn't alloc sweep_skb\n");
594 rc = -ENOMEM;
595 goto done;
596 }
597
598 header = kmalloc(TH_SWEEP_LENGTH, gfp_type());
599
600 if (!header) {
601 dev_kfree_skb_any(sweep_skb);
602 rc = -ENOMEM;
603 goto done;
604 }
605
606 header->th.th_seg = 0x00 ;
607 header->th.th_ch_flag = TH_SWEEP_REQ; /* 0x0f */
608 header->th.th_blk_flag = 0x00;
609 header->th.th_is_xid = 0x00;
610 header->th.th_seq_num = 0x00;
611 header->sw.th_last_seq = ch->th_seq_num;
612
613 memcpy(skb_put(sweep_skb, TH_SWEEP_LENGTH), header, TH_SWEEP_LENGTH);
614
615 kfree(header);
616
617 dev->trans_start = jiffies;
618 skb_queue_tail(&ch->sweep_queue, sweep_skb);
619
620 fsm_addtimer(&ch->sweep_timer, 100, CTC_EVENT_RSWEEP_TIMER, ch);
621
622 return;
623
624done:
625 if (rc != 0) {
626 grp->in_sweep = 0;
627 ctcm_clear_busy(dev);
628 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
629 }
630
631 return;
632}
633
634/*
635 * MPC mode version of transmit_skb
636 */
637static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
638{
639 struct pdu *p_header;
640 struct net_device *dev = ch->netdev;
641 struct ctcm_priv *priv = dev->priv;
642 struct mpc_group *grp = priv->mpcg;
643 struct th_header *header;
644 struct sk_buff *nskb;
645 int rc = 0;
646 int ccw_idx;
647 unsigned long hi;
648 unsigned long saveflags = 0; /* avoids compiler warning */
649 __u16 block_len;
650
651 if (do_debug)
652 ctcm_pr_debug(
653 "ctcm enter: %s(): %s cp=%i ch=0x%p id=%s state=%s\n",
654 __FUNCTION__, dev->name, smp_processor_id(), ch,
655 ch->id, fsm_getstate_str(ch->fsm));
656
657 if ((fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) || grp->in_sweep) {
658 spin_lock_irqsave(&ch->collect_lock, saveflags);
659 atomic_inc(&skb->users);
660 p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type());
661
662 if (!p_header) {
663 printk(KERN_WARNING "ctcm: OUT OF MEMORY IN %s():"
664 " Data Lost \n", __FUNCTION__);
665
666 atomic_dec(&skb->users);
667 dev_kfree_skb_any(skb);
668 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
669 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
670 goto done;
671 }
672
673 p_header->pdu_offset = skb->len;
674 p_header->pdu_proto = 0x01;
675 p_header->pdu_flag = 0x00;
676 if (skb->protocol == ntohs(ETH_P_SNAP)) {
677 p_header->pdu_flag |= PDU_FIRST | PDU_CNTL;
678 } else {
679 p_header->pdu_flag |= PDU_FIRST;
680 }
681 p_header->pdu_seq = 0;
682 memcpy(skb_push(skb, PDU_HEADER_LENGTH), p_header,
683 PDU_HEADER_LENGTH);
684
685 if (do_debug_data) {
686 ctcm_pr_debug("ctcm: %s() Putting on collect_q"
687 " - skb len: %04x \n", __FUNCTION__, skb->len);
688 ctcm_pr_debug("ctcm: %s() pdu header and data"
689 " for up to 32 bytes\n", __FUNCTION__);
690 ctcmpc_dump32((char *)skb->data, skb->len);
691 }
692
693 skb_queue_tail(&ch->collect_queue, skb);
694 ch->collect_len += skb->len;
695 kfree(p_header);
696
697 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
698 goto done;
699 }
700
701 /*
702 * Protect skb against beeing free'd by upper
703 * layers.
704 */
705 atomic_inc(&skb->users);
706
707 block_len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
708 /*
709 * IDAL support in CTCM is broken, so we have to
710 * care about skb's above 2G ourselves.
711 */
712 hi = ((unsigned long)skb->tail + TH_HEADER_LENGTH) >> 31;
713 if (hi) {
714 nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
715 if (!nskb) {
716 printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY"
717 "- Data Lost \n", __FUNCTION__);
718 atomic_dec(&skb->users);
719 dev_kfree_skb_any(skb);
720 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
721 goto done;
722 } else {
723 memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
724 atomic_inc(&nskb->users);
725 atomic_dec(&skb->users);
726 dev_kfree_skb_irq(skb);
727 skb = nskb;
728 }
729 }
730
731 p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type());
732
733 if (!p_header) {
734 printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY"
735 ": Data Lost \n", __FUNCTION__);
736
737 atomic_dec(&skb->users);
738 dev_kfree_skb_any(skb);
739 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
740 goto done;
741 }
742
743 p_header->pdu_offset = skb->len;
744 p_header->pdu_proto = 0x01;
745 p_header->pdu_flag = 0x00;
746 p_header->pdu_seq = 0;
747 if (skb->protocol == ntohs(ETH_P_SNAP)) {
748 p_header->pdu_flag |= PDU_FIRST | PDU_CNTL;
749 } else {
750 p_header->pdu_flag |= PDU_FIRST;
751 }
752 memcpy(skb_push(skb, PDU_HEADER_LENGTH), p_header, PDU_HEADER_LENGTH);
753
754 kfree(p_header);
755
756 if (ch->collect_len > 0) {
757 spin_lock_irqsave(&ch->collect_lock, saveflags);
758 skb_queue_tail(&ch->collect_queue, skb);
759 ch->collect_len += skb->len;
760 skb = skb_dequeue(&ch->collect_queue);
761 ch->collect_len -= skb->len;
762 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
763 }
764
765 p_header = (struct pdu *)skb->data;
766 p_header->pdu_flag |= PDU_LAST;
767
768 ch->prof.txlen += skb->len - PDU_HEADER_LENGTH;
769
770 header = kmalloc(TH_HEADER_LENGTH, gfp_type());
771
772 if (!header) {
773 printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY: Data Lost \n",
774 __FUNCTION__);
775 atomic_dec(&skb->users);
776 dev_kfree_skb_any(skb);
777 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
778 goto done;
779 }
780
781 header->th_seg = 0x00;
782 header->th_ch_flag = TH_HAS_PDU; /* Normal data */
783 header->th_blk_flag = 0x00;
784 header->th_is_xid = 0x00; /* Just data here */
785 ch->th_seq_num++;
786 header->th_seq_num = ch->th_seq_num;
787
788 if (do_debug_data)
789 ctcm_pr_debug("ctcm: %s() ToVTAM_th_seq= %08x\n" ,
790 __FUNCTION__, ch->th_seq_num);
791
792 /* put the TH on the packet */
793 memcpy(skb_push(skb, TH_HEADER_LENGTH), header, TH_HEADER_LENGTH);
794
795 kfree(header);
796
797 if (do_debug_data) {
798 ctcm_pr_debug("ctcm: %s(): skb len: %04x \n",
799 __FUNCTION__, skb->len);
800 ctcm_pr_debug("ctcm: %s(): pdu header and data for up to 32 "
801 "bytes sent to vtam\n", __FUNCTION__);
802 ctcmpc_dump32((char *)skb->data, skb->len);
803 }
804
805 ch->ccw[4].count = skb->len;
806 if (set_normalized_cda(&ch->ccw[4], skb->data)) {
807 /*
808 * idal allocation failed, try via copying to
809 * trans_skb. trans_skb usually has a pre-allocated
810 * idal.
811 */
812 if (ctcm_checkalloc_buffer(ch)) {
813 /*
814 * Remove our header. It gets added
815 * again on retransmit.
816 */
817 atomic_dec(&skb->users);
818 dev_kfree_skb_any(skb);
819 printk(KERN_WARNING "ctcm: %s()OUT OF MEMORY:"
820 " Data Lost \n", __FUNCTION__);
821 fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
822 goto done;
823 }
824
825 skb_reset_tail_pointer(ch->trans_skb);
826 ch->trans_skb->len = 0;
827 ch->ccw[1].count = skb->len;
828 memcpy(skb_put(ch->trans_skb, skb->len), skb->data, skb->len);
829 atomic_dec(&skb->users);
830 dev_kfree_skb_irq(skb);
831 ccw_idx = 0;
832 if (do_debug_data) {
833 ctcm_pr_debug("ctcm: %s() TRANS skb len: %d \n",
834 __FUNCTION__, ch->trans_skb->len);
835 ctcm_pr_debug("ctcm: %s up to 32 bytes of data"
836 " sent to vtam\n", __FUNCTION__);
837 ctcmpc_dump32((char *)ch->trans_skb->data,
838 ch->trans_skb->len);
839 }
840 } else {
841 skb_queue_tail(&ch->io_queue, skb);
842 ccw_idx = 3;
843 }
844 ch->retry = 0;
845 fsm_newstate(ch->fsm, CTC_STATE_TX);
846 fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
847
848 if (do_debug_ccw)
849 ctcmpc_dumpit((char *)&ch->ccw[ccw_idx],
850 sizeof(struct ccw1) * 3);
851
852 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
853 ch->prof.send_stamp = current_kernel_time(); /* xtime */
854 rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx],
855 (unsigned long)ch, 0xff, 0);
856 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
857 if (ccw_idx == 3)
858 ch->prof.doios_single++;
859 if (rc != 0) {
860 fsm_deltimer(&ch->timer);
861 ctcm_ccw_check_rc(ch, rc, "single skb TX");
862 if (ccw_idx == 3)
863 skb_dequeue_tail(&ch->io_queue);
864 } else if (ccw_idx == 0) {
865 priv->stats.tx_packets++;
866 priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH;
867 }
868 if (ch->th_seq_num > 0xf0000000) /* Chose 4Billion at random. */
869 ctcmpc_send_sweep_req(ch);
870
871done:
872 if (do_debug)
873 ctcm_pr_debug("ctcm exit: %s %s()\n", dev->name, __FUNCTION__);
874 return 0;
875}
876
877/**
878 * Start transmission of a packet.
879 * Called from generic network device layer.
880 *
881 * skb Pointer to buffer containing the packet.
882 * dev Pointer to interface struct.
883 *
884 * returns 0 if packet consumed, !0 if packet rejected.
885 * Note: If we return !0, then the packet is free'd by
886 * the generic network layer.
887 */
888/* first merge version - leaving both functions separated */
889static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
890{
891 int rc = 0;
892 struct ctcm_priv *priv;
893
894 CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
895 priv = dev->priv;
896
897 if (skb == NULL) {
898 ctcm_pr_warn("%s: NULL sk_buff passed\n", dev->name);
899 priv->stats.tx_dropped++;
900 return 0;
901 }
902 if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) {
903 ctcm_pr_warn("%s: Got sk_buff with head room < %ld bytes\n",
904 dev->name, LL_HEADER_LENGTH + 2);
905 dev_kfree_skb(skb);
906 priv->stats.tx_dropped++;
907 return 0;
908 }
909
910 /*
911 * If channels are not running, try to restart them
912 * and throw away packet.
913 */
914 if (fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) {
915 fsm_event(priv->fsm, DEV_EVENT_START, dev);
916 dev_kfree_skb(skb);
917 priv->stats.tx_dropped++;
918 priv->stats.tx_errors++;
919 priv->stats.tx_carrier_errors++;
920 return 0;
921 }
922
923 if (ctcm_test_and_set_busy(dev))
924 return -EBUSY;
925
926 dev->trans_start = jiffies;
927 if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0)
928 rc = 1;
929 return rc;
930}
931
932/* unmerged MPC variant of ctcm_tx */
933static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
934{
935 int len = 0;
936 struct ctcm_priv *priv = NULL;
937 struct mpc_group *grp = NULL;
938 struct sk_buff *newskb = NULL;
939
940 if (do_debug)
941 ctcm_pr_debug("ctcmpc enter: %s(): skb:%0lx\n",
942 __FUNCTION__, (unsigned long)skb);
943
944 CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
945 "ctcmpc enter: %s(): skb:%0lx\n",
946 __FUNCTION__, (unsigned long)skb);
947
948 priv = dev->priv;
949 grp = priv->mpcg;
950 /*
951 * Some sanity checks ...
952 */
953 if (skb == NULL) {
954 ctcm_pr_warn("ctcmpc: %s: NULL sk_buff passed\n", dev->name);
955 priv->stats.tx_dropped++;
956 goto done;
957 }
958 if (skb_headroom(skb) < (TH_HEADER_LENGTH + PDU_HEADER_LENGTH)) {
959 CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_WARN,
960 "%s: Got sk_buff with head room < %ld bytes\n",
961 dev->name, TH_HEADER_LENGTH + PDU_HEADER_LENGTH);
962
963 if (do_debug_data)
964 ctcmpc_dump32((char *)skb->data, skb->len);
965
966 len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
967 newskb = __dev_alloc_skb(len, gfp_type() | GFP_DMA);
968
969 if (!newskb) {
970 printk(KERN_WARNING "ctcmpc: %s() OUT OF MEMORY-"
971 "Data Lost\n",
972 __FUNCTION__);
973
974 dev_kfree_skb_any(skb);
975 priv->stats.tx_dropped++;
976 priv->stats.tx_errors++;
977 priv->stats.tx_carrier_errors++;
978 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
979 goto done;
980 }
981 newskb->protocol = skb->protocol;
982 skb_reserve(newskb, TH_HEADER_LENGTH + PDU_HEADER_LENGTH);
983 memcpy(skb_put(newskb, skb->len), skb->data, skb->len);
984 dev_kfree_skb_any(skb);
985 skb = newskb;
986 }
987
988 /*
989 * If channels are not running,
990 * notify anybody about a link failure and throw
991 * away packet.
992 */
993 if ((fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) ||
994 (fsm_getstate(grp->fsm) < MPCG_STATE_XID2INITW)) {
995 dev_kfree_skb_any(skb);
996 printk(KERN_INFO "ctcmpc: %s() DATA RCVD - MPC GROUP "
997 "NOT ACTIVE - DROPPED\n",
998 __FUNCTION__);
999 priv->stats.tx_dropped++;
1000 priv->stats.tx_errors++;
1001 priv->stats.tx_carrier_errors++;
1002 goto done;
1003 }
1004
1005 if (ctcm_test_and_set_busy(dev)) {
1006 printk(KERN_WARNING "%s:DEVICE ERR - UNRECOVERABLE DATA LOSS\n",
1007 __FUNCTION__);
1008 dev_kfree_skb_any(skb);
1009 priv->stats.tx_dropped++;
1010 priv->stats.tx_errors++;
1011 priv->stats.tx_carrier_errors++;
1012 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1013 goto done;
1014 }
1015
1016 dev->trans_start = jiffies;
1017 if (ctcmpc_transmit_skb(priv->channel[WRITE], skb) != 0) {
1018 printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR"
1019 ": Data Lost \n",
1020 __FUNCTION__);
1021 printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR"
1022 " - UNRECOVERABLE DATA LOSS\n",
1023 __FUNCTION__);
1024 dev_kfree_skb_any(skb);
1025 priv->stats.tx_dropped++;
1026 priv->stats.tx_errors++;
1027 priv->stats.tx_carrier_errors++;
1028 ctcm_clear_busy(dev);
1029 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1030 goto done;
1031 }
1032 ctcm_clear_busy(dev);
1033done:
1034 if (do_debug)
1035 MPC_DBF_DEV_NAME(TRACE, dev, "exit");
1036
1037 return 0; /* handle freeing of skb here */
1038}
1039
1040
1041/**
1042 * Sets MTU of an interface.
1043 *
1044 * dev Pointer to interface struct.
1045 * new_mtu The new MTU to use for this interface.
1046 *
1047 * returns 0 on success, -EINVAL if MTU is out of valid range.
1048 * (valid range is 576 .. 65527). If VM is on the
1049 * remote side, maximum MTU is 32760, however this is
1050 * not checked here.
1051 */
1052static int ctcm_change_mtu(struct net_device *dev, int new_mtu)
1053{
1054 struct ctcm_priv *priv;
1055 int max_bufsize;
1056
1057 CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
1058
1059 if (new_mtu < 576 || new_mtu > 65527)
1060 return -EINVAL;
1061
1062 priv = dev->priv;
1063 max_bufsize = priv->channel[READ]->max_bufsize;
1064
1065 if (IS_MPC(priv)) {
1066 if (new_mtu > max_bufsize - TH_HEADER_LENGTH)
1067 return -EINVAL;
1068 dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
1069 } else {
1070 if (new_mtu > max_bufsize - LL_HEADER_LENGTH - 2)
1071 return -EINVAL;
1072 dev->hard_header_len = LL_HEADER_LENGTH + 2;
1073 }
1074 dev->mtu = new_mtu;
1075 return 0;
1076}
1077
1078/**
1079 * Returns interface statistics of a device.
1080 *
1081 * dev Pointer to interface struct.
1082 *
1083 * returns Pointer to stats struct of this interface.
1084 */
1085static struct net_device_stats *ctcm_stats(struct net_device *dev)
1086{
1087 return &((struct ctcm_priv *)dev->priv)->stats;
1088}
1089
1090
1091static void ctcm_netdev_unregister(struct net_device *dev)
1092{
1093 CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
1094 if (!dev)
1095 return;
1096 unregister_netdev(dev);
1097}
1098
1099static int ctcm_netdev_register(struct net_device *dev)
1100{
1101 CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
1102 return register_netdev(dev);
1103}
1104
1105static void ctcm_free_netdevice(struct net_device *dev)
1106{
1107 struct ctcm_priv *priv;
1108 struct mpc_group *grp;
1109
1110 CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
1111
1112 if (!dev)
1113 return;
1114 priv = dev->priv;
1115 if (priv) {
1116 grp = priv->mpcg;
1117 if (grp) {
1118 if (grp->fsm)
1119 kfree_fsm(grp->fsm);
1120 if (grp->xid_skb)
1121 dev_kfree_skb(grp->xid_skb);
1122 if (grp->rcvd_xid_skb)
1123 dev_kfree_skb(grp->rcvd_xid_skb);
1124 tasklet_kill(&grp->mpc_tasklet2);
1125 kfree(grp);
1126 priv->mpcg = NULL;
1127 }
1128 if (priv->fsm) {
1129 kfree_fsm(priv->fsm);
1130 priv->fsm = NULL;
1131 }
1132 kfree(priv->xid);
1133 priv->xid = NULL;
1134 /*
1135 * Note: kfree(priv); is done in "opposite" function of
1136 * allocator function probe_device which is remove_device.
1137 */
1138 }
1139#ifdef MODULE
1140 free_netdev(dev);
1141#endif
1142}
1143
1144struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);
1145
1146void static ctcm_dev_setup(struct net_device *dev)
1147{
1148 dev->open = ctcm_open;
1149 dev->stop = ctcm_close;
1150 dev->get_stats = ctcm_stats;
1151 dev->change_mtu = ctcm_change_mtu;
1152 dev->type = ARPHRD_SLIP;
1153 dev->tx_queue_len = 100;
1154 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
1155}
1156
1157/*
1158 * Initialize everything of the net device except the name and the
1159 * channel structs.
1160 */
1161static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
1162{
1163 struct net_device *dev;
1164 struct mpc_group *grp;
1165 if (!priv)
1166 return NULL;
1167
1168 if (IS_MPC(priv))
1169 dev = alloc_netdev(0, MPC_DEVICE_GENE, ctcm_dev_setup);
1170 else
1171 dev = alloc_netdev(0, CTC_DEVICE_GENE, ctcm_dev_setup);
1172
1173 if (!dev) {
1174 ctcm_pr_err("%s: Out of memory\n", __FUNCTION__);
1175 return NULL;
1176 }
1177 dev->priv = priv;
1178 priv->fsm = init_fsm("ctcmdev", dev_state_names, dev_event_names,
1179 CTCM_NR_DEV_STATES, CTCM_NR_DEV_EVENTS,
1180 dev_fsm, dev_fsm_len, GFP_KERNEL);
1181 if (priv->fsm == NULL) {
1182 CTCMY_DBF_DEV(SETUP, dev, "init_fsm error");
1183 kfree(dev);
1184 return NULL;
1185 }
1186 fsm_newstate(priv->fsm, DEV_STATE_STOPPED);
1187 fsm_settimer(priv->fsm, &priv->restart_timer);
1188
1189 if (IS_MPC(priv)) {
1190 /* MPC Group Initializations */
1191 grp = ctcmpc_init_mpc_group(priv);
1192 if (grp == NULL) {
1193 MPC_DBF_DEV(SETUP, dev, "init_mpc_group error");
1194 kfree(dev);
1195 return NULL;
1196 }
1197 tasklet_init(&grp->mpc_tasklet2,
1198 mpc_group_ready, (unsigned long)dev);
1199 dev->mtu = MPC_BUFSIZE_DEFAULT -
1200 TH_HEADER_LENGTH - PDU_HEADER_LENGTH;
1201
1202 dev->hard_start_xmit = ctcmpc_tx;
1203 dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
1204 priv->buffer_size = MPC_BUFSIZE_DEFAULT;
1205 } else {
1206 dev->mtu = CTCM_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
1207 dev->hard_start_xmit = ctcm_tx;
1208 dev->hard_header_len = LL_HEADER_LENGTH + 2;
1209 }
1210
1211 CTCMY_DBF_DEV(SETUP, dev, "finished");
1212 return dev;
1213}
1214
1215/**
1216 * Main IRQ handler.
1217 *
1218 * cdev The ccw_device the interrupt is for.
1219 * intparm interruption parameter.
1220 * irb interruption response block.
1221 */
1222static void ctcm_irq_handler(struct ccw_device *cdev,
1223 unsigned long intparm, struct irb *irb)
1224{
1225 struct channel *ch;
1226 struct net_device *dev;
1227 struct ctcm_priv *priv;
1228 struct ccwgroup_device *cgdev;
1229
1230 CTCM_DBF_TEXT(TRACE, CTC_DBF_DEBUG, __FUNCTION__);
1231 if (ctcm_check_irb_error(cdev, irb))
1232 return;
1233
1234 cgdev = dev_get_drvdata(&cdev->dev);
1235
1236 /* Check for unsolicited interrupts. */
1237 if (cgdev == NULL) {
1238 ctcm_pr_warn("ctcm: Got unsolicited irq: %s c-%02x d-%02x\n",
1239 cdev->dev.bus_id, irb->scsw.cstat,
1240 irb->scsw.dstat);
1241 return;
1242 }
1243
1244 priv = dev_get_drvdata(&cgdev->dev);
1245
1246 /* Try to extract channel from driver data. */
1247 if (priv->channel[READ]->cdev == cdev)
1248 ch = priv->channel[READ];
1249 else if (priv->channel[WRITE]->cdev == cdev)
1250 ch = priv->channel[WRITE];
1251 else {
1252 ctcm_pr_err("ctcm: Can't determine channel for interrupt, "
1253 "device %s\n", cdev->dev.bus_id);
1254 return;
1255 }
1256
1257 dev = (struct net_device *)(ch->netdev);
1258 if (dev == NULL) {
1259 ctcm_pr_crit("ctcm: %s dev=NULL bus_id=%s, ch=0x%p\n",
1260 __FUNCTION__, cdev->dev.bus_id, ch);
1261 return;
1262 }
1263
1264 if (do_debug)
1265 ctcm_pr_debug("%s: interrupt for device: %s "
1266 "received c-%02x d-%02x\n",
1267 dev->name,
1268 ch->id,
1269 irb->scsw.cstat,
1270 irb->scsw.dstat);
1271
1272 /* Copy interruption response block. */
1273 memcpy(ch->irb, irb, sizeof(struct irb));
1274
1275 /* Check for good subchannel return code, otherwise error message */
1276 if (irb->scsw.cstat) {
1277 fsm_event(ch->fsm, CTC_EVENT_SC_UNKNOWN, ch);
1278 ctcm_pr_warn("%s: subchannel check for dev: %s - %02x %02x\n",
1279 dev->name, ch->id, irb->scsw.cstat,
1280 irb->scsw.dstat);
1281 return;
1282 }
1283
1284 /* Check the reason-code of a unit check */
1285 if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {
1286 ccw_unit_check(ch, irb->ecw[0]);
1287 return;
1288 }
1289 if (irb->scsw.dstat & DEV_STAT_BUSY) {
1290 if (irb->scsw.dstat & DEV_STAT_ATTENTION)
1291 fsm_event(ch->fsm, CTC_EVENT_ATTNBUSY, ch);
1292 else
1293 fsm_event(ch->fsm, CTC_EVENT_BUSY, ch);
1294 return;
1295 }
1296 if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
1297 fsm_event(ch->fsm, CTC_EVENT_ATTN, ch);
1298 return;
1299 }
1300 if ((irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) ||
1301 (irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) ||
1302 (irb->scsw.stctl ==
1303 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))
1304 fsm_event(ch->fsm, CTC_EVENT_FINSTAT, ch);
1305 else
1306 fsm_event(ch->fsm, CTC_EVENT_IRQ, ch);
1307
1308}
1309
1310/**
1311 * Add ctcm specific attributes.
1312 * Add ctcm private data.
1313 *
1314 * cgdev pointer to ccwgroup_device just added
1315 *
1316 * returns 0 on success, !0 on failure.
1317 */
1318static int ctcm_probe_device(struct ccwgroup_device *cgdev)
1319{
1320 struct ctcm_priv *priv;
1321 int rc;
1322
1323 CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s %p", __FUNCTION__, cgdev);
1324
1325 if (!get_device(&cgdev->dev))
1326 return -ENODEV;
1327
1328 priv = kzalloc(sizeof(struct ctcm_priv), GFP_KERNEL);
1329 if (!priv) {
1330 ctcm_pr_err("%s: Out of memory\n", __FUNCTION__);
1331 put_device(&cgdev->dev);
1332 return -ENOMEM;
1333 }
1334
1335 rc = ctcm_add_files(&cgdev->dev);
1336 if (rc) {
1337 kfree(priv);
1338 put_device(&cgdev->dev);
1339 return rc;
1340 }
1341 priv->buffer_size = CTCM_BUFSIZE_DEFAULT;
1342 cgdev->cdev[0]->handler = ctcm_irq_handler;
1343 cgdev->cdev[1]->handler = ctcm_irq_handler;
1344 dev_set_drvdata(&cgdev->dev, priv);
1345
1346 return 0;
1347}
1348
1349/**
1350 * Add a new channel to the list of channels.
1351 * Keeps the channel list sorted.
1352 *
1353 * cdev The ccw_device to be added.
1354 * type The type class of the new channel.
1355 * priv Points to the private data of the ccwgroup_device.
1356 *
1357 * returns 0 on success, !0 on error.
1358 */
1359static int add_channel(struct ccw_device *cdev, enum channel_types type,
1360 struct ctcm_priv *priv)
1361{
1362 struct channel **c = &channels;
1363 struct channel *ch;
1364 int ccw_num;
1365 int rc = 0;
1366
1367 CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
1368 ch = kzalloc(sizeof(struct channel), GFP_KERNEL);
1369 if (ch == NULL)
1370 goto nomem_return;
1371
1372 ch->protocol = priv->protocol;
1373 if (IS_MPC(priv)) {
1374 ch->discontact_th = (struct th_header *)
1375 kzalloc(TH_HEADER_LENGTH, gfp_type());
1376 if (ch->discontact_th == NULL)
1377 goto nomem_return;
1378
1379 ch->discontact_th->th_blk_flag = TH_DISCONTACT;
1380 tasklet_init(&ch->ch_disc_tasklet,
1381 mpc_action_send_discontact, (unsigned long)ch);
1382
1383 tasklet_init(&ch->ch_tasklet, ctcmpc_bh, (unsigned long)ch);
1384 ch->max_bufsize = (MPC_BUFSIZE_DEFAULT - 35);
1385 ccw_num = 17;
1386 } else
1387 ccw_num = 8;
1388
1389 ch->ccw = (struct ccw1 *)
1390 kzalloc(ccw_num * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
1391 if (ch->ccw == NULL)
1392 goto nomem_return;
1393
1394 ch->cdev = cdev;
1395 snprintf(ch->id, CTCM_ID_SIZE, "ch-%s", cdev->dev.bus_id);
1396 ch->type = type;
1397
1398 /**
1399 * "static" ccws are used in the following way:
1400 *
1401 * ccw[0..2] (Channel program for generic I/O):
1402 * 0: prepare
1403 * 1: read or write (depending on direction) with fixed
1404 * buffer (idal allocated once when buffer is allocated)
1405 * 2: nop
1406 * ccw[3..5] (Channel program for direct write of packets)
1407 * 3: prepare
1408 * 4: write (idal allocated on every write).
1409 * 5: nop
1410 * ccw[6..7] (Channel program for initial channel setup):
1411 * 6: set extended mode
1412 * 7: nop
1413 *
1414 * ch->ccw[0..5] are initialized in ch_action_start because
1415 * the channel's direction is yet unknown here.
1416 *
1417 * ccws used for xid2 negotiations
1418 * ch-ccw[8-14] need to be used for the XID exchange either
1419 * X side XID2 Processing
1420 * 8: write control
1421 * 9: write th
1422 * 10: write XID
1423 * 11: read th from secondary
1424 * 12: read XID from secondary
1425 * 13: read 4 byte ID
1426 * 14: nop
1427 * Y side XID Processing
1428 * 8: sense
1429 * 9: read th
1430 * 10: read XID
1431 * 11: write th
1432 * 12: write XID
1433 * 13: write 4 byte ID
1434 * 14: nop
1435 *
1436 * ccws used for double noop due to VM timing issues
1437 * which result in unrecoverable Busy on channel
1438 * 15: nop
1439 * 16: nop
1440 */
1441 ch->ccw[6].cmd_code = CCW_CMD_SET_EXTENDED;
1442 ch->ccw[6].flags = CCW_FLAG_SLI;
1443
1444 ch->ccw[7].cmd_code = CCW_CMD_NOOP;
1445 ch->ccw[7].flags = CCW_FLAG_SLI;
1446
1447 if (IS_MPC(priv)) {
1448 ch->ccw[15].cmd_code = CCW_CMD_WRITE;
1449 ch->ccw[15].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1450 ch->ccw[15].count = TH_HEADER_LENGTH;
1451 ch->ccw[15].cda = virt_to_phys(ch->discontact_th);
1452
1453 ch->ccw[16].cmd_code = CCW_CMD_NOOP;
1454 ch->ccw[16].flags = CCW_FLAG_SLI;
1455
1456 ch->fsm = init_fsm(ch->id, ctc_ch_state_names,
1457 ctc_ch_event_names, CTC_MPC_NR_STATES,
1458 CTC_MPC_NR_EVENTS, ctcmpc_ch_fsm,
1459 mpc_ch_fsm_len, GFP_KERNEL);
1460 } else {
1461 ch->fsm = init_fsm(ch->id, ctc_ch_state_names,
1462 ctc_ch_event_names, CTC_NR_STATES,
1463 CTC_NR_EVENTS, ch_fsm,
1464 ch_fsm_len, GFP_KERNEL);
1465 }
1466 if (ch->fsm == NULL)
1467 goto free_return;
1468
1469 fsm_newstate(ch->fsm, CTC_STATE_IDLE);
1470
1471 ch->irb = kzalloc(sizeof(struct irb), GFP_KERNEL);
1472 if (ch->irb == NULL)
1473 goto nomem_return;
1474
1475 while (*c && ctcm_less_than((*c)->id, ch->id))
1476 c = &(*c)->next;
1477
1478 if (*c && (!strncmp((*c)->id, ch->id, CTCM_ID_SIZE))) {
1479 CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
1480 "%s (%s) already in list, using old entry",
1481 __FUNCTION__, (*c)->id);
1482
1483 goto free_return;
1484 }
1485
1486 spin_lock_init(&ch->collect_lock);
1487
1488 fsm_settimer(ch->fsm, &ch->timer);
1489 skb_queue_head_init(&ch->io_queue);
1490 skb_queue_head_init(&ch->collect_queue);
1491
1492 if (IS_MPC(priv)) {
1493 fsm_settimer(ch->fsm, &ch->sweep_timer);
1494 skb_queue_head_init(&ch->sweep_queue);
1495 }
1496 ch->next = *c;
1497 *c = ch;
1498 return 0;
1499
1500nomem_return:
1501 ctcm_pr_warn("ctcm: Out of memory in %s\n", __FUNCTION__);
1502 rc = -ENOMEM;
1503
1504free_return: /* note that all channel pointers are 0 or valid */
1505 kfree(ch->ccw); /* TODO: check that again */
1506 kfree(ch->discontact_th);
1507 kfree_fsm(ch->fsm);
1508 kfree(ch->irb);
1509 kfree(ch);
1510 return rc;
1511}
1512
1513/*
1514 * Return type of a detected device.
1515 */
1516static enum channel_types get_channel_type(struct ccw_device_id *id)
1517{
1518 enum channel_types type;
1519 type = (enum channel_types)id->driver_info;
1520
1521 if (type == channel_type_ficon)
1522 type = channel_type_escon;
1523
1524 return type;
1525}
1526
1527/**
1528 *
1529 * Setup an interface.
1530 *
1531 * cgdev Device to be setup.
1532 *
1533 * returns 0 on success, !0 on failure.
1534 */
1535static int ctcm_new_device(struct ccwgroup_device *cgdev)
1536{
1537 char read_id[CTCM_ID_SIZE];
1538 char write_id[CTCM_ID_SIZE];
1539 int direction;
1540 enum channel_types type;
1541 struct ctcm_priv *priv;
1542 struct net_device *dev;
1543 int ret;
1544
1545 CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
1546
1547 priv = dev_get_drvdata(&cgdev->dev);
1548 if (!priv)
1549 return -ENODEV;
1550
1551 type = get_channel_type(&cgdev->cdev[0]->id);
1552
1553 snprintf(read_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
1554 snprintf(write_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id);
1555
1556 ret = add_channel(cgdev->cdev[0], type, priv);
1557 if (ret)
1558 return ret;
1559 ret = add_channel(cgdev->cdev[1], type, priv);
1560 if (ret)
1561 return ret;
1562
1563 ret = ccw_device_set_online(cgdev->cdev[0]);
1564 if (ret != 0) {
1565 CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN,
1566 "ccw_device_set_online (cdev[0]) failed ");
1567 ctcm_pr_warn("ccw_device_set_online (cdev[0]) failed "
1568 "with ret = %d\n", ret);
1569 }
1570
1571 ret = ccw_device_set_online(cgdev->cdev[1]);
1572 if (ret != 0) {
1573 CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN,
1574 "ccw_device_set_online (cdev[1]) failed ");
1575 ctcm_pr_warn("ccw_device_set_online (cdev[1]) failed "
1576 "with ret = %d\n", ret);
1577 }
1578
1579 dev = ctcm_init_netdevice(priv);
1580
1581 if (dev == NULL) {
1582 ctcm_pr_warn("ctcm_init_netdevice failed\n");
1583 goto out;
1584 }
1585
1586 for (direction = READ; direction <= WRITE; direction++) {
1587 priv->channel[direction] =
1588 channel_get(type, direction == READ ? read_id : write_id,
1589 direction);
1590 if (priv->channel[direction] == NULL) {
1591 if (direction == WRITE)
1592 channel_free(priv->channel[READ]);
1593 ctcm_free_netdevice(dev);
1594 goto out;
1595 }
1596 priv->channel[direction]->netdev = dev;
1597 priv->channel[direction]->protocol = priv->protocol;
1598 priv->channel[direction]->max_bufsize = priv->buffer_size;
1599 }
1600 /* sysfs magic */
1601 SET_NETDEV_DEV(dev, &cgdev->dev);
1602
1603 if (ctcm_netdev_register(dev) != 0) {
1604 ctcm_free_netdevice(dev);
1605 goto out;
1606 }
1607
1608 if (ctcm_add_attributes(&cgdev->dev)) {
1609 ctcm_netdev_unregister(dev);
1610/* dev->priv = NULL; why that ???? */
1611 ctcm_free_netdevice(dev);
1612 goto out;
1613 }
1614
1615 strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));
1616
1617 CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
1618 "setup(%s) ok : r/w = %s / %s, proto : %d",
1619 dev->name, priv->channel[READ]->id,
1620 priv->channel[WRITE]->id, priv->protocol);
1621
1622 return 0;
1623out:
1624 ccw_device_set_offline(cgdev->cdev[1]);
1625 ccw_device_set_offline(cgdev->cdev[0]);
1626
1627 return -ENODEV;
1628}
1629
1630/**
1631 * Shutdown an interface.
1632 *
1633 * cgdev Device to be shut down.
1634 *
1635 * returns 0 on success, !0 on failure.
1636 */
1637static int ctcm_shutdown_device(struct ccwgroup_device *cgdev)
1638{
1639 struct ctcm_priv *priv;
1640 struct net_device *dev;
1641
1642 priv = dev_get_drvdata(&cgdev->dev);
1643 if (!priv)
1644 return -ENODEV;
1645
1646 if (priv->channel[READ]) {
1647 dev = priv->channel[READ]->netdev;
1648 CTCM_DBF_DEV(SETUP, dev, "");
1649 /* Close the device */
1650 ctcm_close(dev);
1651 dev->flags &= ~IFF_RUNNING;
1652 ctcm_remove_attributes(&cgdev->dev);
1653 channel_free(priv->channel[READ]);
1654 } else
1655 dev = NULL;
1656
1657 if (priv->channel[WRITE])
1658 channel_free(priv->channel[WRITE]);
1659
1660 if (dev) {
1661 ctcm_netdev_unregister(dev);
1662/* dev->priv = NULL; why that ??? */
1663 ctcm_free_netdevice(dev);
1664 }
1665
1666 if (priv->fsm)
1667 kfree_fsm(priv->fsm);
1668
1669 ccw_device_set_offline(cgdev->cdev[1]);
1670 ccw_device_set_offline(cgdev->cdev[0]);
1671
1672 if (priv->channel[READ])
1673 channel_remove(priv->channel[READ]);
1674 if (priv->channel[WRITE])
1675 channel_remove(priv->channel[WRITE]);
1676 priv->channel[READ] = priv->channel[WRITE] = NULL;
1677
1678 return 0;
1679
1680}
1681
1682
1683static void ctcm_remove_device(struct ccwgroup_device *cgdev)
1684{
1685 struct ctcm_priv *priv;
1686
1687 CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, __FUNCTION__);
1688
1689 priv = dev_get_drvdata(&cgdev->dev);
1690 if (!priv)
1691 return;
1692 if (cgdev->state == CCWGROUP_ONLINE)
1693 ctcm_shutdown_device(cgdev);
1694 ctcm_remove_files(&cgdev->dev);
1695 dev_set_drvdata(&cgdev->dev, NULL);
1696 kfree(priv);
1697 put_device(&cgdev->dev);
1698}
1699
1700static struct ccwgroup_driver ctcm_group_driver = {
1701 .owner = THIS_MODULE,
1702 .name = CTC_DRIVER_NAME,
1703 .max_slaves = 2,
1704 .driver_id = 0xC3E3C3D4, /* CTCM */
1705 .probe = ctcm_probe_device,
1706 .remove = ctcm_remove_device,
1707 .set_online = ctcm_new_device,
1708 .set_offline = ctcm_shutdown_device,
1709};
1710
1711
1712/*
1713 * Module related routines
1714 */
1715
1716/*
1717 * Prepare to be unloaded. Free IRQ's and release all resources.
1718 * This is called just before this module is unloaded. It is
1719 * not called, if the usage count is !0, so we don't need to check
1720 * for that.
1721 */
1722static void __exit ctcm_exit(void)
1723{
1724 unregister_cu3088_discipline(&ctcm_group_driver);
1725 ctcm_unregister_dbf_views();
1726 ctcm_pr_info("CTCM driver unloaded\n");
1727}
1728
1729/*
1730 * Print Banner.
1731 */
1732static void print_banner(void)
1733{
1734 printk(KERN_INFO "CTCM driver initialized\n");
1735}
1736
1737/**
1738 * Initialize module.
1739 * This is called just after the module is loaded.
1740 *
1741 * returns 0 on success, !0 on error.
1742 */
1743static int __init ctcm_init(void)
1744{
1745 int ret;
1746
1747 channels = NULL;
1748
1749 ret = ctcm_register_dbf_views();
1750 if (ret) {
1751 ctcm_pr_crit("ctcm_init failed with ctcm_register_dbf_views "
1752 "rc = %d\n", ret);
1753 return ret;
1754 }
1755 ret = register_cu3088_discipline(&ctcm_group_driver);
1756 if (ret) {
1757 ctcm_unregister_dbf_views();
1758 ctcm_pr_crit("ctcm_init failed with register_cu3088_discipline "
1759 "(rc = %d)\n", ret);
1760 return ret;
1761 }
1762 print_banner();
1763 return ret;
1764}
1765
1766module_init(ctcm_init);
1767module_exit(ctcm_exit);
1768
1769MODULE_AUTHOR("Peter Tiedemann <ptiedem@de.ibm.com>");
1770MODULE_DESCRIPTION("Network driver for S/390 CTC + CTCMPC (SNA)");
1771MODULE_LICENSE("GPL");
1772
diff --git a/drivers/s390/net/ctcm_main.h b/drivers/s390/net/ctcm_main.h
new file mode 100644
index 000000000000..95b0c0b6ebc6
--- /dev/null
+++ b/drivers/s390/net/ctcm_main.h
@@ -0,0 +1,287 @@
1/*
2 * drivers/s390/net/ctcm_main.h
3 *
4 * Copyright IBM Corp. 2001, 2007
5 * Authors: Fritz Elfert (felfert@millenux.com)
6 * Peter Tiedemann (ptiedem@de.ibm.com)
7 */
8
9#ifndef _CTCM_MAIN_H_
10#define _CTCM_MAIN_H_
11
12#include <asm/ccwdev.h>
13#include <asm/ccwgroup.h>
14
15#include <linux/skbuff.h>
16#include <linux/netdevice.h>
17
18#include "fsm.h"
19#include "cu3088.h"
20#include "ctcm_dbug.h"
21#include "ctcm_mpc.h"
22
23#define CTC_DRIVER_NAME "ctcm"
24#define CTC_DEVICE_NAME "ctc"
25#define CTC_DEVICE_GENE "ctc%d"
26#define MPC_DEVICE_NAME "mpc"
27#define MPC_DEVICE_GENE "mpc%d"
28
29#define CHANNEL_FLAGS_READ 0
30#define CHANNEL_FLAGS_WRITE 1
31#define CHANNEL_FLAGS_INUSE 2
32#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
33#define CHANNEL_FLAGS_FAILED 8
34#define CHANNEL_FLAGS_WAITIRQ 16
35#define CHANNEL_FLAGS_RWMASK 1
36#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
37
38#define LOG_FLAG_ILLEGALPKT 1
39#define LOG_FLAG_ILLEGALSIZE 2
40#define LOG_FLAG_OVERRUN 4
41#define LOG_FLAG_NOMEM 8
42
43#define ctcm_pr_debug(fmt, arg...) printk(KERN_DEBUG fmt, ##arg)
44#define ctcm_pr_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
45#define ctcm_pr_notice(fmt, arg...) printk(KERN_NOTICE fmt, ##arg)
46#define ctcm_pr_warn(fmt, arg...) printk(KERN_WARNING fmt, ##arg)
47#define ctcm_pr_emerg(fmt, arg...) printk(KERN_EMERG fmt, ##arg)
48#define ctcm_pr_err(fmt, arg...) printk(KERN_ERR fmt, ##arg)
49#define ctcm_pr_crit(fmt, arg...) printk(KERN_CRIT fmt, ##arg)
50
51/*
52 * CCW commands, used in this driver.
53 */
54#define CCW_CMD_WRITE 0x01
55#define CCW_CMD_READ 0x02
56#define CCW_CMD_NOOP 0x03
57#define CCW_CMD_TIC 0x08
58#define CCW_CMD_SENSE_CMD 0x14
59#define CCW_CMD_WRITE_CTL 0x17
60#define CCW_CMD_SET_EXTENDED 0xc3
61#define CCW_CMD_PREPARE 0xe3
62
63#define CTCM_PROTO_S390 0
64#define CTCM_PROTO_LINUX 1
65#define CTCM_PROTO_LINUX_TTY 2
66#define CTCM_PROTO_OS390 3
67#define CTCM_PROTO_MPC 4
68#define CTCM_PROTO_MAX 4
69
70#define CTCM_BUFSIZE_LIMIT 65535
71#define CTCM_BUFSIZE_DEFAULT 32768
72#define MPC_BUFSIZE_DEFAULT CTCM_BUFSIZE_LIMIT
73
74#define CTCM_TIME_1_SEC 1000
75#define CTCM_TIME_5_SEC 5000
76#define CTCM_TIME_10_SEC 10000
77
78#define CTCM_INITIAL_BLOCKLEN 2
79
80#define READ 0
81#define WRITE 1
82
83#define CTCM_ID_SIZE BUS_ID_SIZE+3
84
85struct ctcm_profile {
86 unsigned long maxmulti;
87 unsigned long maxcqueue;
88 unsigned long doios_single;
89 unsigned long doios_multi;
90 unsigned long txlen;
91 unsigned long tx_time;
92 struct timespec send_stamp;
93};
94
95/*
96 * Definition of one channel
97 */
98struct channel {
99 struct channel *next;
100 char id[CTCM_ID_SIZE];
101 struct ccw_device *cdev;
102 /*
103 * Type of this channel.
104 * CTC/A or Escon for valid channels.
105 */
106 enum channel_types type;
107 /*
108 * Misc. flags. See CHANNEL_FLAGS_... below
109 */
110 __u32 flags;
111 __u16 protocol; /* protocol of this channel (4 = MPC) */
112 /*
113 * I/O and irq related stuff
114 */
115 struct ccw1 *ccw;
116 struct irb *irb;
117 /*
118 * RX/TX buffer size
119 */
120 int max_bufsize;
121 struct sk_buff *trans_skb; /* transmit/receive buffer */
122 struct sk_buff_head io_queue; /* universal I/O queue */
123 struct tasklet_struct ch_tasklet; /* MPC ONLY */
124 /*
125 * TX queue for collecting skb's during busy.
126 */
127 struct sk_buff_head collect_queue;
128 /*
129 * Amount of data in collect_queue.
130 */
131 int collect_len;
132 /*
133 * spinlock for collect_queue and collect_len
134 */
135 spinlock_t collect_lock;
136 /*
137 * Timer for detecting unresposive
138 * I/O operations.
139 */
140 fsm_timer timer;
141 /* MPC ONLY section begin */
142 __u32 th_seq_num; /* SNA TH seq number */
143 __u8 th_seg;
144 __u32 pdu_seq;
145 struct sk_buff *xid_skb;
146 char *xid_skb_data;
147 struct th_header *xid_th;
148 struct xid2 *xid;
149 char *xid_id;
150 struct th_header *rcvd_xid_th;
151 struct xid2 *rcvd_xid;
152 char *rcvd_xid_id;
153 __u8 in_mpcgroup;
154 fsm_timer sweep_timer;
155 struct sk_buff_head sweep_queue;
156 struct th_header *discontact_th;
157 struct tasklet_struct ch_disc_tasklet;
158 /* MPC ONLY section end */
159
160 int retry; /* retry counter for misc. operations */
161 fsm_instance *fsm; /* finite state machine of this channel */
162 struct net_device *netdev; /* corresponding net_device */
163 struct ctcm_profile prof;
164 unsigned char *trans_skb_data;
165 __u16 logflags;
166};
167
168struct ctcm_priv {
169 struct net_device_stats stats;
170 unsigned long tbusy;
171
172 /* The MPC group struct of this interface */
173 struct mpc_group *mpcg; /* MPC only */
174 struct xid2 *xid; /* MPC only */
175
176 /* The finite state machine of this interface */
177 fsm_instance *fsm;
178
179 /* The protocol of this device */
180 __u16 protocol;
181
182 /* Timer for restarting after I/O Errors */
183 fsm_timer restart_timer;
184
185 int buffer_size; /* ctc only */
186
187 struct channel *channel[2];
188};
189
190int ctcm_open(struct net_device *dev);
191int ctcm_close(struct net_device *dev);
192
193/*
194 * prototypes for non-static sysfs functions
195 */
196int ctcm_add_attributes(struct device *dev);
197void ctcm_remove_attributes(struct device *dev);
198int ctcm_add_files(struct device *dev);
199void ctcm_remove_files(struct device *dev);
200
201/*
202 * Compatibility macros for busy handling
203 * of network devices.
204 */
205static inline void ctcm_clear_busy_do(struct net_device *dev)
206{
207 clear_bit(0, &(((struct ctcm_priv *)dev->priv)->tbusy));
208 netif_wake_queue(dev);
209}
210
211static inline void ctcm_clear_busy(struct net_device *dev)
212{
213 struct mpc_group *grp;
214 grp = ((struct ctcm_priv *)dev->priv)->mpcg;
215
216 if (!(grp && grp->in_sweep))
217 ctcm_clear_busy_do(dev);
218}
219
220
221static inline int ctcm_test_and_set_busy(struct net_device *dev)
222{
223 netif_stop_queue(dev);
224 return test_and_set_bit(0, &(((struct ctcm_priv *)dev->priv)->tbusy));
225}
226
227extern int loglevel;
228extern struct channel *channels;
229
230void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb);
231
232/*
233 * Functions related to setup and device detection.
234 */
235
236static inline int ctcm_less_than(char *id1, char *id2)
237{
238 unsigned long dev1, dev2;
239
240 id1 = id1 + 5;
241 id2 = id2 + 5;
242
243 dev1 = simple_strtoul(id1, &id1, 16);
244 dev2 = simple_strtoul(id2, &id2, 16);
245
246 return (dev1 < dev2);
247}
248
249int ctcm_ch_alloc_buffer(struct channel *ch);
250
251static inline int ctcm_checkalloc_buffer(struct channel *ch)
252{
253 if (ch->trans_skb == NULL)
254 return ctcm_ch_alloc_buffer(ch);
255 if (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED) {
256 dev_kfree_skb(ch->trans_skb);
257 return ctcm_ch_alloc_buffer(ch);
258 }
259 return 0;
260}
261
262struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);
263
264/* test if protocol attribute (of struct ctcm_priv or struct channel)
265 * has MPC protocol setting. Type is not checked
266 */
267#define IS_MPC(p) ((p)->protocol == CTCM_PROTO_MPC)
268
269/* test if struct ctcm_priv of struct net_device has MPC protocol setting */
270#define IS_MPCDEV(d) IS_MPC((struct ctcm_priv *)d->priv)
271
272static inline gfp_t gfp_type(void)
273{
274 return in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
275}
276
277/*
278 * Definition of our link level header.
279 */
280struct ll_header {
281 __u16 length;
282 __u16 type;
283 __u16 unused;
284};
285#define LL_HEADER_LENGTH (sizeof(struct ll_header))
286
287#endif
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
new file mode 100644
index 000000000000..044addee64a2
--- /dev/null
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -0,0 +1,2472 @@
1/*
2 * drivers/s390/net/ctcm_mpc.c
3 *
4 * Copyright IBM Corp. 2004, 2007
5 * Authors: Belinda Thompson (belindat@us.ibm.com)
6 * Andy Richter (richtera@us.ibm.com)
7 * Peter Tiedemann (ptiedem@de.ibm.com)
8 */
9
10/*
11 This module exports functions to be used by CCS:
12 EXPORT_SYMBOL(ctc_mpc_alloc_channel);
13 EXPORT_SYMBOL(ctc_mpc_establish_connectivity);
14 EXPORT_SYMBOL(ctc_mpc_dealloc_ch);
15 EXPORT_SYMBOL(ctc_mpc_flow_control);
16*/
17
18#undef DEBUG
19#undef DEBUGDATA
20#undef DEBUGCCW
21
22#include <linux/version.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/errno.h>
28#include <linux/types.h>
29#include <linux/interrupt.h>
30#include <linux/timer.h>
31#include <linux/sched.h>
32
33#include <linux/signal.h>
34#include <linux/string.h>
35#include <linux/proc_fs.h>
36
37#include <linux/ip.h>
38#include <linux/if_arp.h>
39#include <linux/tcp.h>
40#include <linux/skbuff.h>
41#include <linux/ctype.h>
42#include <linux/netdevice.h>
43#include <net/dst.h>
44
45#include <linux/io.h> /* instead of <asm/io.h> ok ? */
46#include <asm/ccwdev.h>
47#include <asm/ccwgroup.h>
48#include <linux/bitops.h> /* instead of <asm/bitops.h> ok ? */
49#include <linux/uaccess.h> /* instead of <asm/uaccess.h> ok ? */
50#include <linux/wait.h>
51#include <linux/moduleparam.h>
52#include <asm/idals.h>
53
54#include "cu3088.h"
55#include "ctcm_mpc.h"
56#include "ctcm_main.h"
57#include "ctcm_fsms.h"
58
59static const struct xid2 init_xid = {
60 .xid2_type_id = XID_FM2,
61 .xid2_len = 0x45,
62 .xid2_adj_id = 0,
63 .xid2_rlen = 0x31,
64 .xid2_resv1 = 0,
65 .xid2_flag1 = 0,
66 .xid2_fmtt = 0,
67 .xid2_flag4 = 0x80,
68 .xid2_resv2 = 0,
69 .xid2_tgnum = 0,
70 .xid2_sender_id = 0,
71 .xid2_flag2 = 0,
72 .xid2_option = XID2_0,
73 .xid2_resv3 = "\x00",
74 .xid2_resv4 = 0,
75 .xid2_dlc_type = XID2_READ_SIDE,
76 .xid2_resv5 = 0,
77 .xid2_mpc_flag = 0,
78 .xid2_resv6 = 0,
79 .xid2_buf_len = (MPC_BUFSIZE_DEFAULT - 35),
80};
81
82static const struct th_header thnorm = {
83 .th_seg = 0x00,
84 .th_ch_flag = TH_IS_XID,
85 .th_blk_flag = TH_DATA_IS_XID,
86 .th_is_xid = 0x01,
87 .th_seq_num = 0x00000000,
88};
89
90static const struct th_header thdummy = {
91 .th_seg = 0x00,
92 .th_ch_flag = 0x00,
93 .th_blk_flag = TH_DATA_IS_XID,
94 .th_is_xid = 0x01,
95 .th_seq_num = 0x00000000,
96};
97
98/*
99 * Definition of one MPC group
100 */
101
102/*
103 * Compatibility macros for busy handling
104 * of network devices.
105 */
106
107static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb);
108
109/*
110 * MPC Group state machine actions (static prototypes)
111 */
112static void mpc_action_nop(fsm_instance *fsm, int event, void *arg);
113static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg);
114static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg);
115static void mpc_action_timeout(fsm_instance *fi, int event, void *arg);
116static int mpc_validate_xid(struct mpcg_info *mpcginfo);
117static void mpc_action_yside_xid(fsm_instance *fsm, int event, void *arg);
118static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg);
119static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg);
120static void mpc_action_xside_xid(fsm_instance *fsm, int event, void *arg);
121static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg);
122static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg);
123
124#ifdef DEBUGDATA
125/*-------------------------------------------------------------------*
126* Dump buffer format *
127* *
128*--------------------------------------------------------------------*/
129void ctcmpc_dumpit(char *buf, int len)
130{
131 __u32 ct, sw, rm, dup;
132 char *ptr, *rptr;
133 char tbuf[82], tdup[82];
134 #if (UTS_MACHINE == s390x)
135 char addr[22];
136 #else
137 char addr[12];
138 #endif
139 char boff[12];
140 char bhex[82], duphex[82];
141 char basc[40];
142
143 sw = 0;
144 rptr = ptr = buf;
145 rm = 16;
146 duphex[0] = 0x00;
147 dup = 0;
148
149 for (ct = 0; ct < len; ct++, ptr++, rptr++) {
150 if (sw == 0) {
151 #if (UTS_MACHINE == s390x)
152 sprintf(addr, "%16.16lx", (unsigned long)rptr);
153 #else
154 sprintf(addr, "%8.8X", (__u32)rptr);
155 #endif
156
157 sprintf(boff, "%4.4X", (__u32)ct);
158 bhex[0] = '\0';
159 basc[0] = '\0';
160 }
161 if ((sw == 4) || (sw == 12))
162 strcat(bhex, " ");
163 if (sw == 8)
164 strcat(bhex, " ");
165
166 #if (UTS_MACHINE == s390x)
167 sprintf(tbuf, "%2.2lX", (unsigned long)*ptr);
168 #else
169 sprintf(tbuf, "%2.2X", (__u32)*ptr);
170 #endif
171
172 tbuf[2] = '\0';
173 strcat(bhex, tbuf);
174 if ((0 != isprint(*ptr)) && (*ptr >= 0x20))
175 basc[sw] = *ptr;
176 else
177 basc[sw] = '.';
178
179 basc[sw+1] = '\0';
180 sw++;
181 rm--;
182 if (sw == 16) {
183 if ((strcmp(duphex, bhex)) != 0) {
184 if (dup != 0) {
185 sprintf(tdup, "Duplicate as above "
186 "to %s", addr);
187 printk(KERN_INFO " "
188 " --- %s ---\n", tdup);
189 }
190 printk(KERN_INFO " %s (+%s) : %s [%s]\n",
191 addr, boff, bhex, basc);
192 dup = 0;
193 strcpy(duphex, bhex);
194 } else
195 dup++;
196
197 sw = 0;
198 rm = 16;
199 }
200 } /* endfor */
201
202 if (sw != 0) {
203 for ( ; rm > 0; rm--, sw++) {
204 if ((sw == 4) || (sw == 12))
205 strcat(bhex, " ");
206 if (sw == 8)
207 strcat(bhex, " ");
208 strcat(bhex, " ");
209 strcat(basc, " ");
210 }
211 if (dup != 0) {
212 sprintf(tdup, "Duplicate as above to %s", addr);
213 printk(KERN_INFO " "
214 " --- %s ---\n", tdup);
215 }
216 printk(KERN_INFO " %s (+%s) : %s [%s]\n",
217 addr, boff, bhex, basc);
218 } else {
219 if (dup >= 1) {
220 sprintf(tdup, "Duplicate as above to %s", addr);
221 printk(KERN_INFO " "
222 " --- %s ---\n", tdup);
223 }
224 if (dup != 0) {
225 printk(KERN_INFO " %s (+%s) : %s [%s]\n",
226 addr, boff, bhex, basc);
227 }
228 }
229
230 return;
231
232} /* end of ctcmpc_dumpit */
233#endif
234
235#ifdef DEBUGDATA
236/*
237 * Dump header and first 16 bytes of an sk_buff for debugging purposes.
238 *
239 * skb The sk_buff to dump.
240 * offset Offset relative to skb-data, where to start the dump.
241 */
242void ctcmpc_dump_skb(struct sk_buff *skb, int offset)
243{
244 unsigned char *p = skb->data;
245 struct th_header *header;
246 struct pdu *pheader;
247 int bl = skb->len;
248 int i;
249
250 if (p == NULL)
251 return;
252
253 p += offset;
254 header = (struct th_header *)p;
255
256 printk(KERN_INFO "dump:\n");
257 printk(KERN_INFO "skb len=%d \n", skb->len);
258 if (skb->len > 2) {
259 switch (header->th_ch_flag) {
260 case TH_HAS_PDU:
261 break;
262 case 0x00:
263 case TH_IS_XID:
264 if ((header->th_blk_flag == TH_DATA_IS_XID) &&
265 (header->th_is_xid == 0x01))
266 goto dumpth;
267 case TH_SWEEP_REQ:
268 goto dumpth;
269 case TH_SWEEP_RESP:
270 goto dumpth;
271 default:
272 break;
273 }
274
275 pheader = (struct pdu *)p;
276 printk(KERN_INFO "pdu->offset: %d hex: %04x\n",
277 pheader->pdu_offset, pheader->pdu_offset);
278 printk(KERN_INFO "pdu->flag : %02x\n", pheader->pdu_flag);
279 printk(KERN_INFO "pdu->proto : %02x\n", pheader->pdu_proto);
280 printk(KERN_INFO "pdu->seq : %02x\n", pheader->pdu_seq);
281 goto dumpdata;
282
283dumpth:
284 printk(KERN_INFO "th->seg : %02x\n", header->th_seg);
285 printk(KERN_INFO "th->ch : %02x\n", header->th_ch_flag);
286 printk(KERN_INFO "th->blk_flag: %02x\n", header->th_blk_flag);
287 printk(KERN_INFO "th->type : %s\n",
288 (header->th_is_xid) ? "DATA" : "XID");
289 printk(KERN_INFO "th->seqnum : %04x\n", header->th_seq_num);
290
291 }
292dumpdata:
293 if (bl > 32)
294 bl = 32;
295 printk(KERN_INFO "data: ");
296 for (i = 0; i < bl; i++)
297 printk(KERN_INFO "%02x%s", *p++, (i % 16) ? " " : "\n<7>");
298 printk(KERN_INFO "\n");
299}
300#endif
301
302/*
303 * ctc_mpc_alloc_channel
304 * (exported interface)
305 *
306 * Device Initialization :
307 * ACTPATH driven IO operations
308 */
309int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int))
310{
311 char device[20];
312 struct net_device *dev;
313 struct mpc_group *grp;
314 struct ctcm_priv *priv;
315
316 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
317
318 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
319 dev = __dev_get_by_name(&init_net, device);
320
321 if (dev == NULL) {
322 printk(KERN_INFO "ctc_mpc_alloc_channel %s dev=NULL\n", device);
323 return 1;
324 }
325
326 priv = dev->priv;
327 grp = priv->mpcg;
328 if (!grp)
329 return 1;
330
331 grp->allochanfunc = callback;
332 grp->port_num = port_num;
333 grp->port_persist = 1;
334
335 ctcm_pr_debug("ctcmpc: %s called for device %s state=%s\n",
336 __FUNCTION__,
337 dev->name,
338 fsm_getstate_str(grp->fsm));
339
340 switch (fsm_getstate(grp->fsm)) {
341 case MPCG_STATE_INOP:
342 /* Group is in the process of terminating */
343 grp->alloc_called = 1;
344 break;
345 case MPCG_STATE_RESET:
346 /* MPC Group will transition to state */
347 /* MPCG_STATE_XID2INITW iff the minimum number */
348 /* of 1 read and 1 write channel have successfully*/
349 /* activated */
350 /*fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);*/
351 if (callback)
352 grp->send_qllc_disc = 1;
353 case MPCG_STATE_XID0IOWAIT:
354 fsm_deltimer(&grp->timer);
355 grp->outstanding_xid2 = 0;
356 grp->outstanding_xid7 = 0;
357 grp->outstanding_xid7_p2 = 0;
358 grp->saved_xid2 = NULL;
359 if (callback)
360 ctcm_open(dev);
361 fsm_event(priv->fsm, DEV_EVENT_START, dev);
362 break;
363 case MPCG_STATE_READY:
364 /* XID exchanges completed after PORT was activated */
365 /* Link station already active */
366 /* Maybe timing issue...retry callback */
367 grp->allocchan_callback_retries++;
368 if (grp->allocchan_callback_retries < 4) {
369 if (grp->allochanfunc)
370 grp->allochanfunc(grp->port_num,
371 grp->group_max_buflen);
372 } else {
373 /* there are problems...bail out */
374 /* there may be a state mismatch so restart */
375 grp->port_persist = 1;
376 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
377 grp->allocchan_callback_retries = 0;
378 }
379 break;
380 default:
381 return 0;
382
383 }
384
385 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
386 return 0;
387}
388EXPORT_SYMBOL(ctc_mpc_alloc_channel);
389
390/*
391 * ctc_mpc_establish_connectivity
392 * (exported interface)
393 */
394void ctc_mpc_establish_connectivity(int port_num,
395 void (*callback)(int, int, int))
396{
397 char device[20];
398 struct net_device *dev;
399 struct mpc_group *grp;
400 struct ctcm_priv *priv;
401 struct channel *rch, *wch;
402
403 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
404
405 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
406 dev = __dev_get_by_name(&init_net, device);
407
408 if (dev == NULL) {
409 printk(KERN_INFO "ctc_mpc_establish_connectivity "
410 "%s dev=NULL\n", device);
411 return;
412 }
413 priv = dev->priv;
414 rch = priv->channel[READ];
415 wch = priv->channel[WRITE];
416
417 grp = priv->mpcg;
418
419 ctcm_pr_debug("ctcmpc: %s() called for device %s state=%s\n",
420 __FUNCTION__, dev->name,
421 fsm_getstate_str(grp->fsm));
422
423 grp->estconnfunc = callback;
424 grp->port_num = port_num;
425
426 switch (fsm_getstate(grp->fsm)) {
427 case MPCG_STATE_READY:
428 /* XID exchanges completed after PORT was activated */
429 /* Link station already active */
430 /* Maybe timing issue...retry callback */
431 fsm_deltimer(&grp->timer);
432 grp->estconn_callback_retries++;
433 if (grp->estconn_callback_retries < 4) {
434 if (grp->estconnfunc) {
435 grp->estconnfunc(grp->port_num, 0,
436 grp->group_max_buflen);
437 grp->estconnfunc = NULL;
438 }
439 } else {
440 /* there are problems...bail out */
441 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
442 grp->estconn_callback_retries = 0;
443 }
444 break;
445 case MPCG_STATE_INOP:
446 case MPCG_STATE_RESET:
447 /* MPC Group is not ready to start XID - min num of */
448 /* 1 read and 1 write channel have not been acquired*/
449 printk(KERN_WARNING "ctcmpc: %s() REJECTED ACTIVE XID Req"
450 "uest - Channel Pair is not Active\n", __FUNCTION__);
451 if (grp->estconnfunc) {
452 grp->estconnfunc(grp->port_num, -1, 0);
453 grp->estconnfunc = NULL;
454 }
455 break;
456 case MPCG_STATE_XID2INITW:
457 /* alloc channel was called but no XID exchange */
458 /* has occurred. initiate xside XID exchange */
459 /* make sure yside XID0 processing has not started */
460 if ((fsm_getstate(rch->fsm) > CH_XID0_PENDING) ||
461 (fsm_getstate(wch->fsm) > CH_XID0_PENDING)) {
462 printk(KERN_WARNING "mpc: %s() ABORT ACTIVE XID"
463 " Request- PASSIVE XID in process\n"
464 , __FUNCTION__);
465 break;
466 }
467 grp->send_qllc_disc = 1;
468 fsm_newstate(grp->fsm, MPCG_STATE_XID0IOWAIT);
469 fsm_deltimer(&grp->timer);
470 fsm_addtimer(&grp->timer, MPC_XID_TIMEOUT_VALUE,
471 MPCG_EVENT_TIMER, dev);
472 grp->outstanding_xid7 = 0;
473 grp->outstanding_xid7_p2 = 0;
474 grp->saved_xid2 = NULL;
475 if ((rch->in_mpcgroup) &&
476 (fsm_getstate(rch->fsm) == CH_XID0_PENDING))
477 fsm_event(grp->fsm, MPCG_EVENT_XID0DO, rch);
478 else {
479 printk(KERN_WARNING "mpc: %s() Unable to start"
480 " ACTIVE XID0 on read channel\n",
481 __FUNCTION__);
482 if (grp->estconnfunc) {
483 grp->estconnfunc(grp->port_num, -1, 0);
484 grp->estconnfunc = NULL;
485 }
486 fsm_deltimer(&grp->timer);
487 goto done;
488 }
489 if ((wch->in_mpcgroup) &&
490 (fsm_getstate(wch->fsm) == CH_XID0_PENDING))
491 fsm_event(grp->fsm, MPCG_EVENT_XID0DO, wch);
492 else {
493 printk(KERN_WARNING "mpc: %s() Unable to start"
494 " ACTIVE XID0 on write channel\n",
495 __FUNCTION__);
496 if (grp->estconnfunc) {
497 grp->estconnfunc(grp->port_num, -1, 0);
498 grp->estconnfunc = NULL;
499 }
500 fsm_deltimer(&grp->timer);
501 goto done;
502 }
503 break;
504 case MPCG_STATE_XID0IOWAIT:
505 /* already in active XID negotiations */
506 default:
507 break;
508 }
509
510done:
511 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
512 return;
513}
514EXPORT_SYMBOL(ctc_mpc_establish_connectivity);
515
516/*
517 * ctc_mpc_dealloc_ch
518 * (exported interface)
519 */
520void ctc_mpc_dealloc_ch(int port_num)
521{
522 struct net_device *dev;
523 char device[20];
524 struct ctcm_priv *priv;
525 struct mpc_group *grp;
526
527 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
528 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
529 dev = __dev_get_by_name(&init_net, device);
530
531 if (dev == NULL) {
532 printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device);
533 goto done;
534 }
535
536 ctcm_pr_debug("ctcmpc:%s %s() called for device %s refcount=%d\n",
537 dev->name, __FUNCTION__,
538 dev->name, atomic_read(&dev->refcnt));
539
540 priv = dev->priv;
541 if (priv == NULL) {
542 printk(KERN_INFO "%s() %s priv=NULL\n",
543 __FUNCTION__, device);
544 goto done;
545 }
546 fsm_deltimer(&priv->restart_timer);
547
548 grp = priv->mpcg;
549 if (grp == NULL) {
550 printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device);
551 goto done;
552 }
553 grp->channels_terminating = 0;
554
555 fsm_deltimer(&grp->timer);
556
557 grp->allochanfunc = NULL;
558 grp->estconnfunc = NULL;
559 grp->port_persist = 0;
560 grp->send_qllc_disc = 0;
561 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
562
563 ctcm_close(dev);
564done:
565 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
566 return;
567}
568EXPORT_SYMBOL(ctc_mpc_dealloc_ch);
569
570/*
571 * ctc_mpc_flow_control
572 * (exported interface)
573 */
574void ctc_mpc_flow_control(int port_num, int flowc)
575{
576 char device[20];
577 struct ctcm_priv *priv;
578 struct mpc_group *grp;
579 struct net_device *dev;
580 struct channel *rch;
581 int mpcg_state;
582
583 ctcm_pr_debug("ctcmpc enter: %s() %i\n", __FUNCTION__, flowc);
584
585 sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
586 dev = __dev_get_by_name(&init_net, device);
587
588 if (dev == NULL) {
589 printk(KERN_INFO "ctc_mpc_flow_control %s dev=NULL\n", device);
590 return;
591 }
592
593 ctcm_pr_debug("ctcmpc: %s %s called \n", dev->name, __FUNCTION__);
594
595 priv = dev->priv;
596 if (priv == NULL) {
597 printk(KERN_INFO "ctcmpc:%s() %s priv=NULL\n",
598 __FUNCTION__, device);
599 return;
600 }
601 grp = priv->mpcg;
602 rch = priv->channel[READ];
603
604 mpcg_state = fsm_getstate(grp->fsm);
605 switch (flowc) {
606 case 1:
607 if (mpcg_state == MPCG_STATE_FLOWC)
608 break;
609 if (mpcg_state == MPCG_STATE_READY) {
610 if (grp->flow_off_called == 1)
611 grp->flow_off_called = 0;
612 else
613 fsm_newstate(grp->fsm, MPCG_STATE_FLOWC);
614 break;
615 }
616 break;
617 case 0:
618 if (mpcg_state == MPCG_STATE_FLOWC) {
619 fsm_newstate(grp->fsm, MPCG_STATE_READY);
620 /* ensure any data that has accumulated */
621 /* on the io_queue will now be sen t */
622 tasklet_schedule(&rch->ch_tasklet);
623 }
624 /* possible race condition */
625 if (mpcg_state == MPCG_STATE_READY) {
626 grp->flow_off_called = 1;
627 break;
628 }
629 break;
630 }
631
632 ctcm_pr_debug("ctcmpc exit: %s() %i\n", __FUNCTION__, flowc);
633}
634EXPORT_SYMBOL(ctc_mpc_flow_control);
635
636static int mpc_send_qllc_discontact(struct net_device *);
637
638/*
639 * helper function of ctcmpc_unpack_skb
640*/
641static void mpc_rcvd_sweep_resp(struct mpcg_info *mpcginfo)
642{
643 struct channel *rch = mpcginfo->ch;
644 struct net_device *dev = rch->netdev;
645 struct ctcm_priv *priv = dev->priv;
646 struct mpc_group *grp = priv->mpcg;
647 struct channel *ch = priv->channel[WRITE];
648
649 if (do_debug)
650 ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
651 __FUNCTION__, ch, ch->id);
652
653 if (do_debug_data)
654 ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
655
656 grp->sweep_rsp_pend_num--;
657
658 if ((grp->sweep_req_pend_num == 0) &&
659 (grp->sweep_rsp_pend_num == 0)) {
660 fsm_deltimer(&ch->sweep_timer);
661 grp->in_sweep = 0;
662 rch->th_seq_num = 0x00;
663 ch->th_seq_num = 0x00;
664 ctcm_clear_busy_do(dev);
665 }
666
667 kfree(mpcginfo);
668
669 return;
670
671}
672
673/*
674 * helper function of mpc_rcvd_sweep_req
675 * which is a helper of ctcmpc_unpack_skb
676 */
677static void ctcmpc_send_sweep_resp(struct channel *rch)
678{
679 struct net_device *dev = rch->netdev;
680 struct ctcm_priv *priv = dev->priv;
681 struct mpc_group *grp = priv->mpcg;
682 int rc = 0;
683 struct th_sweep *header;
684 struct sk_buff *sweep_skb;
685 struct channel *ch = priv->channel[WRITE];
686
687 if (do_debug)
688 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
689 __FUNCTION__, rch, rch->id);
690
691 sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT,
692 GFP_ATOMIC|GFP_DMA);
693 if (sweep_skb == NULL) {
694 printk(KERN_INFO "Couldn't alloc sweep_skb\n");
695 rc = -ENOMEM;
696 goto done;
697 }
698
699 header = (struct th_sweep *)
700 kmalloc(sizeof(struct th_sweep), gfp_type());
701
702 if (!header) {
703 dev_kfree_skb_any(sweep_skb);
704 rc = -ENOMEM;
705 goto done;
706 }
707
708 header->th.th_seg = 0x00 ;
709 header->th.th_ch_flag = TH_SWEEP_RESP;
710 header->th.th_blk_flag = 0x00;
711 header->th.th_is_xid = 0x00;
712 header->th.th_seq_num = 0x00;
713 header->sw.th_last_seq = ch->th_seq_num;
714
715 memcpy(skb_put(sweep_skb, TH_SWEEP_LENGTH), header, TH_SWEEP_LENGTH);
716
717 kfree(header);
718
719 dev->trans_start = jiffies;
720 skb_queue_tail(&ch->sweep_queue, sweep_skb);
721
722 fsm_addtimer(&ch->sweep_timer, 100, CTC_EVENT_RSWEEP_TIMER, ch);
723
724 return;
725
726done:
727 if (rc != 0) {
728 grp->in_sweep = 0;
729 ctcm_clear_busy_do(dev);
730 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
731 }
732
733 return;
734}
735
736/*
737 * helper function of ctcmpc_unpack_skb
738 */
739static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo)
740{
741 struct channel *rch = mpcginfo->ch;
742 struct net_device *dev = rch->netdev;
743 struct ctcm_priv *priv = dev->priv;
744 struct mpc_group *grp = priv->mpcg;
745 struct channel *ch = priv->channel[WRITE];
746
747 if (do_debug)
748 CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
749 " %s(): ch=0x%p id=%s\n", __FUNCTION__, ch, ch->id);
750
751 if (grp->in_sweep == 0) {
752 grp->in_sweep = 1;
753 ctcm_test_and_set_busy(dev);
754 grp->sweep_req_pend_num = grp->active_channels[READ];
755 grp->sweep_rsp_pend_num = grp->active_channels[READ];
756 }
757
758 if (do_debug_data)
759 ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
760
761 grp->sweep_req_pend_num--;
762 ctcmpc_send_sweep_resp(ch);
763 kfree(mpcginfo);
764 return;
765}
766
767/*
768 * MPC Group Station FSM definitions
769 */
770static const char *mpcg_event_names[] = {
771 [MPCG_EVENT_INOP] = "INOP Condition",
772 [MPCG_EVENT_DISCONC] = "Discontact Received",
773 [MPCG_EVENT_XID0DO] = "Channel Active - Start XID",
774 [MPCG_EVENT_XID2] = "XID2 Received",
775 [MPCG_EVENT_XID2DONE] = "XID0 Complete",
776 [MPCG_EVENT_XID7DONE] = "XID7 Complete",
777 [MPCG_EVENT_TIMER] = "XID Setup Timer",
778 [MPCG_EVENT_DOIO] = "XID DoIO",
779};
780
781static const char *mpcg_state_names[] = {
782 [MPCG_STATE_RESET] = "Reset",
783 [MPCG_STATE_INOP] = "INOP",
784 [MPCG_STATE_XID2INITW] = "Passive XID- XID0 Pending Start",
785 [MPCG_STATE_XID2INITX] = "Passive XID- XID0 Pending Complete",
786 [MPCG_STATE_XID7INITW] = "Passive XID- XID7 Pending P1 Start",
787 [MPCG_STATE_XID7INITX] = "Passive XID- XID7 Pending P2 Complete",
788 [MPCG_STATE_XID0IOWAIT] = "Active XID- XID0 Pending Start",
789 [MPCG_STATE_XID0IOWAIX] = "Active XID- XID0 Pending Complete",
790 [MPCG_STATE_XID7INITI] = "Active XID- XID7 Pending Start",
791 [MPCG_STATE_XID7INITZ] = "Active XID- XID7 Pending Complete ",
792 [MPCG_STATE_XID7INITF] = "XID - XID7 Complete ",
793 [MPCG_STATE_FLOWC] = "FLOW CONTROL ON",
794 [MPCG_STATE_READY] = "READY",
795};
796
797/*
798 * The MPC Group Station FSM
799 * 22 events
800 */
801static const fsm_node mpcg_fsm[] = {
802 { MPCG_STATE_RESET, MPCG_EVENT_INOP, mpc_action_go_inop },
803 { MPCG_STATE_INOP, MPCG_EVENT_INOP, mpc_action_nop },
804 { MPCG_STATE_FLOWC, MPCG_EVENT_INOP, mpc_action_go_inop },
805
806 { MPCG_STATE_READY, MPCG_EVENT_DISCONC, mpc_action_discontact },
807 { MPCG_STATE_READY, MPCG_EVENT_INOP, mpc_action_go_inop },
808
809 { MPCG_STATE_XID2INITW, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
810 { MPCG_STATE_XID2INITW, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
811 { MPCG_STATE_XID2INITW, MPCG_EVENT_INOP, mpc_action_go_inop },
812 { MPCG_STATE_XID2INITW, MPCG_EVENT_TIMER, mpc_action_timeout },
813 { MPCG_STATE_XID2INITW, MPCG_EVENT_DOIO, mpc_action_yside_xid },
814
815 { MPCG_STATE_XID2INITX, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
816 { MPCG_STATE_XID2INITX, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
817 { MPCG_STATE_XID2INITX, MPCG_EVENT_INOP, mpc_action_go_inop },
818 { MPCG_STATE_XID2INITX, MPCG_EVENT_TIMER, mpc_action_timeout },
819 { MPCG_STATE_XID2INITX, MPCG_EVENT_DOIO, mpc_action_yside_xid },
820
821 { MPCG_STATE_XID7INITW, MPCG_EVENT_XID2DONE, mpc_action_doxid7 },
822 { MPCG_STATE_XID7INITW, MPCG_EVENT_DISCONC, mpc_action_discontact },
823 { MPCG_STATE_XID7INITW, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
824 { MPCG_STATE_XID7INITW, MPCG_EVENT_INOP, mpc_action_go_inop },
825 { MPCG_STATE_XID7INITW, MPCG_EVENT_TIMER, mpc_action_timeout },
826 { MPCG_STATE_XID7INITW, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
827 { MPCG_STATE_XID7INITW, MPCG_EVENT_DOIO, mpc_action_yside_xid },
828
829 { MPCG_STATE_XID7INITX, MPCG_EVENT_DISCONC, mpc_action_discontact },
830 { MPCG_STATE_XID7INITX, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
831 { MPCG_STATE_XID7INITX, MPCG_EVENT_INOP, mpc_action_go_inop },
832 { MPCG_STATE_XID7INITX, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
833 { MPCG_STATE_XID7INITX, MPCG_EVENT_TIMER, mpc_action_timeout },
834 { MPCG_STATE_XID7INITX, MPCG_EVENT_DOIO, mpc_action_yside_xid },
835
836 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
837 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_DISCONC, mpc_action_discontact },
838 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
839 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_INOP, mpc_action_go_inop },
840 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_TIMER, mpc_action_timeout },
841 { MPCG_STATE_XID0IOWAIT, MPCG_EVENT_DOIO, mpc_action_xside_xid },
842
843 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_XID0DO, mpc_action_doxid0 },
844 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_DISCONC, mpc_action_discontact },
845 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_XID2, mpc_action_rcvd_xid0 },
846 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_INOP, mpc_action_go_inop },
847 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_TIMER, mpc_action_timeout },
848 { MPCG_STATE_XID0IOWAIX, MPCG_EVENT_DOIO, mpc_action_xside_xid },
849
850 { MPCG_STATE_XID7INITI, MPCG_EVENT_XID2DONE, mpc_action_doxid7 },
851 { MPCG_STATE_XID7INITI, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
852 { MPCG_STATE_XID7INITI, MPCG_EVENT_DISCONC, mpc_action_discontact },
853 { MPCG_STATE_XID7INITI, MPCG_EVENT_INOP, mpc_action_go_inop },
854 { MPCG_STATE_XID7INITI, MPCG_EVENT_TIMER, mpc_action_timeout },
855 { MPCG_STATE_XID7INITI, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
856 { MPCG_STATE_XID7INITI, MPCG_EVENT_DOIO, mpc_action_xside_xid },
857
858 { MPCG_STATE_XID7INITZ, MPCG_EVENT_XID2, mpc_action_rcvd_xid7 },
859 { MPCG_STATE_XID7INITZ, MPCG_EVENT_XID7DONE, mpc_action_doxid7 },
860 { MPCG_STATE_XID7INITZ, MPCG_EVENT_DISCONC, mpc_action_discontact },
861 { MPCG_STATE_XID7INITZ, MPCG_EVENT_INOP, mpc_action_go_inop },
862 { MPCG_STATE_XID7INITZ, MPCG_EVENT_TIMER, mpc_action_timeout },
863 { MPCG_STATE_XID7INITZ, MPCG_EVENT_DOIO, mpc_action_xside_xid },
864
865 { MPCG_STATE_XID7INITF, MPCG_EVENT_INOP, mpc_action_go_inop },
866 { MPCG_STATE_XID7INITF, MPCG_EVENT_XID7DONE, mpc_action_go_ready },
867};
868
869static int mpcg_fsm_len = ARRAY_SIZE(mpcg_fsm);
870
871/*
872 * MPC Group Station FSM action
873 * CTCM_PROTO_MPC only
874 */
875static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg)
876{
877 struct net_device *dev = arg;
878 struct ctcm_priv *priv = NULL;
879 struct mpc_group *grp = NULL;
880
881 if (dev == NULL) {
882 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
883 return;
884 }
885
886 ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__);
887
888 priv = dev->priv;
889 if (priv == NULL) {
890 printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
891 return;
892 }
893
894 grp = priv->mpcg;
895 if (grp == NULL) {
896 printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__);
897 return;
898 }
899
900 fsm_deltimer(&grp->timer);
901
902 if (grp->saved_xid2->xid2_flag2 == 0x40) {
903 priv->xid->xid2_flag2 = 0x00;
904 if (grp->estconnfunc) {
905 grp->estconnfunc(grp->port_num, 1,
906 grp->group_max_buflen);
907 grp->estconnfunc = NULL;
908 } else if (grp->allochanfunc)
909 grp->send_qllc_disc = 1;
910 goto done;
911 }
912
913 grp->port_persist = 1;
914 grp->out_of_sequence = 0;
915 grp->estconn_called = 0;
916
917 tasklet_hi_schedule(&grp->mpc_tasklet2);
918
919 ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
920 return;
921
922done:
923 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
924
925
926 ctcm_pr_info("ctcmpc: %s()failure occurred\n", __FUNCTION__);
927}
928
929/*
930 * helper of ctcm_init_netdevice
931 * CTCM_PROTO_MPC only
932 */
933void mpc_group_ready(unsigned long adev)
934{
935 struct net_device *dev = (struct net_device *)adev;
936 struct ctcm_priv *priv = NULL;
937 struct mpc_group *grp = NULL;
938 struct channel *ch = NULL;
939
940
941 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
942
943 if (dev == NULL) {
944 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
945 return;
946 }
947
948 priv = dev->priv;
949 if (priv == NULL) {
950 printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
951 return;
952 }
953
954 grp = priv->mpcg;
955 if (grp == NULL) {
956 printk(KERN_INFO "ctcmpc:%s() grp=NULL\n", __FUNCTION__);
957 return;
958 }
959
960 printk(KERN_NOTICE "ctcmpc: %s GROUP TRANSITIONED TO READY"
961 " maxbuf:%d\n",
962 dev->name, grp->group_max_buflen);
963
964 fsm_newstate(grp->fsm, MPCG_STATE_READY);
965
966 /* Put up a read on the channel */
967 ch = priv->channel[READ];
968 ch->pdu_seq = 0;
969 if (do_debug_data)
970 ctcm_pr_debug("ctcmpc: %s() ToDCM_pdu_seq= %08x\n" ,
971 __FUNCTION__, ch->pdu_seq);
972
973 ctcmpc_chx_rxidle(ch->fsm, CTC_EVENT_START, ch);
974 /* Put the write channel in idle state */
975 ch = priv->channel[WRITE];
976 if (ch->collect_len > 0) {
977 spin_lock(&ch->collect_lock);
978 ctcm_purge_skb_queue(&ch->collect_queue);
979 ch->collect_len = 0;
980 spin_unlock(&ch->collect_lock);
981 }
982 ctcm_chx_txidle(ch->fsm, CTC_EVENT_START, ch);
983
984 ctcm_clear_busy(dev);
985
986 if (grp->estconnfunc) {
987 grp->estconnfunc(grp->port_num, 0,
988 grp->group_max_buflen);
989 grp->estconnfunc = NULL;
990 } else
991 if (grp->allochanfunc)
992 grp->allochanfunc(grp->port_num,
993 grp->group_max_buflen);
994
995 grp->send_qllc_disc = 1;
996 grp->changed_side = 0;
997
998 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
999 return;
1000
1001}
1002
1003/*
1004 * Increment the MPC Group Active Channel Counts
1005 * helper of dev_action (called from channel fsm)
1006 */
1007int mpc_channel_action(struct channel *ch, int direction, int action)
1008{
1009 struct net_device *dev = ch->netdev;
1010 struct ctcm_priv *priv;
1011 struct mpc_group *grp = NULL;
1012 int rc = 0;
1013
1014 if (do_debug)
1015 ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
1016 __FUNCTION__, ch, ch->id);
1017
1018 if (dev == NULL) {
1019 printk(KERN_INFO "ctcmpc_channel_action %i dev=NULL\n",
1020 action);
1021 rc = 1;
1022 goto done;
1023 }
1024
1025 priv = dev->priv;
1026 if (priv == NULL) {
1027 printk(KERN_INFO
1028 "ctcmpc_channel_action%i priv=NULL, dev=%s\n",
1029 action, dev->name);
1030 rc = 2;
1031 goto done;
1032 }
1033
1034 grp = priv->mpcg;
1035
1036 if (grp == NULL) {
1037 printk(KERN_INFO "ctcmpc: %s()%i mpcgroup=NULL, dev=%s\n",
1038 __FUNCTION__, action, dev->name);
1039 rc = 3;
1040 goto done;
1041 }
1042
1043 ctcm_pr_info(
1044 "ctcmpc: %s() %i(): Grp:%s total_channel_paths=%i "
1045 "active_channels read=%i, write=%i\n",
1046 __FUNCTION__,
1047 action,
1048 fsm_getstate_str(grp->fsm),
1049 grp->num_channel_paths,
1050 grp->active_channels[READ],
1051 grp->active_channels[WRITE]);
1052
1053 if ((action == MPC_CHANNEL_ADD) && (ch->in_mpcgroup == 0)) {
1054 grp->num_channel_paths++;
1055 grp->active_channels[direction]++;
1056 grp->outstanding_xid2++;
1057 ch->in_mpcgroup = 1;
1058
1059 if (ch->xid_skb != NULL)
1060 dev_kfree_skb_any(ch->xid_skb);
1061
1062 ch->xid_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT,
1063 GFP_ATOMIC | GFP_DMA);
1064 if (ch->xid_skb == NULL) {
1065 printk(KERN_INFO "ctcmpc: %s()"
1066 "Couldn't alloc ch xid_skb\n", __FUNCTION__);
1067 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1068 return 1;
1069 }
1070 ch->xid_skb_data = ch->xid_skb->data;
1071 ch->xid_th = (struct th_header *)ch->xid_skb->data;
1072 skb_put(ch->xid_skb, TH_HEADER_LENGTH);
1073 ch->xid = (struct xid2 *)skb_tail_pointer(ch->xid_skb);
1074 skb_put(ch->xid_skb, XID2_LENGTH);
1075 ch->xid_id = skb_tail_pointer(ch->xid_skb);
1076 ch->xid_skb->data = ch->xid_skb_data;
1077 skb_reset_tail_pointer(ch->xid_skb);
1078 ch->xid_skb->len = 0;
1079
1080 memcpy(skb_put(ch->xid_skb, grp->xid_skb->len),
1081 grp->xid_skb->data,
1082 grp->xid_skb->len);
1083
1084 ch->xid->xid2_dlc_type = ((CHANNEL_DIRECTION(ch->flags) == READ)
1085 ? XID2_READ_SIDE : XID2_WRITE_SIDE);
1086
1087 if (CHANNEL_DIRECTION(ch->flags) == WRITE)
1088 ch->xid->xid2_buf_len = 0x00;
1089
1090 ch->xid_skb->data = ch->xid_skb_data;
1091 skb_reset_tail_pointer(ch->xid_skb);
1092 ch->xid_skb->len = 0;
1093
1094 fsm_newstate(ch->fsm, CH_XID0_PENDING);
1095
1096 if ((grp->active_channels[READ] > 0) &&
1097 (grp->active_channels[WRITE] > 0) &&
1098 (fsm_getstate(grp->fsm) < MPCG_STATE_XID2INITW)) {
1099 fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);
1100 printk(KERN_NOTICE "ctcmpc: %s MPC GROUP "
1101 "CHANNELS ACTIVE\n", dev->name);
1102 }
1103 } else if ((action == MPC_CHANNEL_REMOVE) &&
1104 (ch->in_mpcgroup == 1)) {
1105 ch->in_mpcgroup = 0;
1106 grp->num_channel_paths--;
1107 grp->active_channels[direction]--;
1108
1109 if (ch->xid_skb != NULL)
1110 dev_kfree_skb_any(ch->xid_skb);
1111 ch->xid_skb = NULL;
1112
1113 if (grp->channels_terminating)
1114 goto done;
1115
1116 if (((grp->active_channels[READ] == 0) &&
1117 (grp->active_channels[WRITE] > 0))
1118 || ((grp->active_channels[WRITE] == 0) &&
1119 (grp->active_channels[READ] > 0)))
1120 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1121 }
1122
1123done:
1124
1125 if (do_debug) {
1126 ctcm_pr_debug(
1127 "ctcmpc: %s() %i Grp:%s ttl_chan_paths=%i "
1128 "active_chans read=%i, write=%i\n",
1129 __FUNCTION__,
1130 action,
1131 fsm_getstate_str(grp->fsm),
1132 grp->num_channel_paths,
1133 grp->active_channels[READ],
1134 grp->active_channels[WRITE]);
1135
1136 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
1137 __FUNCTION__, ch, ch->id);
1138 }
1139 return rc;
1140
1141}
1142
1143/**
1144 * Unpack a just received skb and hand it over to
1145 * upper layers.
1146 * special MPC version of unpack_skb.
1147 *
1148 * ch The channel where this skb has been received.
1149 * pskb The received skb.
1150 */
1151static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
1152{
1153 struct net_device *dev = ch->netdev;
1154 struct ctcm_priv *priv = dev->priv;
1155 struct mpc_group *grp = priv->mpcg;
1156 struct pdu *curr_pdu;
1157 struct mpcg_info *mpcginfo;
1158 struct th_header *header = NULL;
1159 struct th_sweep *sweep = NULL;
1160 int pdu_last_seen = 0;
1161 __u32 new_len;
1162 struct sk_buff *skb;
1163 int skblen;
1164 int sendrc = 0;
1165
1166 if (do_debug)
1167 ctcm_pr_debug("ctcmpc enter: %s() %s cp:%i ch:%s\n",
1168 __FUNCTION__, dev->name, smp_processor_id(), ch->id);
1169
1170 header = (struct th_header *)pskb->data;
1171 if ((header->th_seg == 0) &&
1172 (header->th_ch_flag == 0) &&
1173 (header->th_blk_flag == 0) &&
1174 (header->th_seq_num == 0))
1175 /* nothing for us */ goto done;
1176
1177 if (do_debug_data) {
1178 ctcm_pr_debug("ctcmpc: %s() th_header\n", __FUNCTION__);
1179 ctcmpc_dumpit((char *)header, TH_HEADER_LENGTH);
1180 ctcm_pr_debug("ctcmpc: %s() pskb len: %04x \n",
1181 __FUNCTION__, pskb->len);
1182 }
1183
1184 pskb->dev = dev;
1185 pskb->ip_summed = CHECKSUM_UNNECESSARY;
1186 skb_pull(pskb, TH_HEADER_LENGTH);
1187
1188 if (likely(header->th_ch_flag == TH_HAS_PDU)) {
1189 if (do_debug_data)
1190 ctcm_pr_debug("ctcmpc: %s() came into th_has_pdu\n",
1191 __FUNCTION__);
1192 if ((fsm_getstate(grp->fsm) == MPCG_STATE_FLOWC) ||
1193 ((fsm_getstate(grp->fsm) == MPCG_STATE_READY) &&
1194 (header->th_seq_num != ch->th_seq_num + 1) &&
1195 (ch->th_seq_num != 0))) {
1196 /* This is NOT the next segment *
1197 * we are not the correct race winner *
1198 * go away and let someone else win *
1199 * BUT..this only applies if xid negot *
1200 * is done *
1201 */
1202 grp->out_of_sequence += 1;
1203 __skb_push(pskb, TH_HEADER_LENGTH);
1204 skb_queue_tail(&ch->io_queue, pskb);
1205 if (do_debug_data)
1206 ctcm_pr_debug("ctcmpc: %s() th_seq_num "
1207 "expect:%08x got:%08x\n", __FUNCTION__,
1208 ch->th_seq_num + 1, header->th_seq_num);
1209
1210 return;
1211 }
1212 grp->out_of_sequence = 0;
1213 ch->th_seq_num = header->th_seq_num;
1214
1215 if (do_debug_data)
1216 ctcm_pr_debug("ctcmpc: %s() FromVTAM_th_seq=%08x\n",
1217 __FUNCTION__, ch->th_seq_num);
1218
1219 if (unlikely(fsm_getstate(grp->fsm) != MPCG_STATE_READY))
1220 goto done;
1221 pdu_last_seen = 0;
1222 while ((pskb->len > 0) && !pdu_last_seen) {
1223 curr_pdu = (struct pdu *)pskb->data;
1224 if (do_debug_data) {
1225 ctcm_pr_debug("ctcm: %s() pdu_header\n",
1226 __FUNCTION__);
1227 ctcmpc_dumpit((char *)pskb->data,
1228 PDU_HEADER_LENGTH);
1229 ctcm_pr_debug("ctcm: %s() pskb len: %04x \n",
1230 __FUNCTION__, pskb->len);
1231 }
1232 skb_pull(pskb, PDU_HEADER_LENGTH);
1233
1234 if (curr_pdu->pdu_flag & PDU_LAST)
1235 pdu_last_seen = 1;
1236 if (curr_pdu->pdu_flag & PDU_CNTL)
1237 pskb->protocol = htons(ETH_P_SNAP);
1238 else
1239 pskb->protocol = htons(ETH_P_SNA_DIX);
1240
1241 if ((pskb->len <= 0) || (pskb->len > ch->max_bufsize)) {
1242 printk(KERN_INFO
1243 "%s Illegal packet size %d "
1244 "received "
1245 "dropping\n", dev->name,
1246 pskb->len);
1247 priv->stats.rx_dropped++;
1248 priv->stats.rx_length_errors++;
1249 goto done;
1250 }
1251 skb_reset_mac_header(pskb);
1252 new_len = curr_pdu->pdu_offset;
1253 if (do_debug_data)
1254 ctcm_pr_debug("ctcmpc: %s() new_len: %04x \n",
1255 __FUNCTION__, new_len);
1256 if ((new_len == 0) || (new_len > pskb->len)) {
1257 /* should never happen */
1258 /* pskb len must be hosed...bail out */
1259 printk(KERN_INFO
1260 "ctcmpc: %s(): invalid pdu"
1261 " offset of %04x - data may be"
1262 "lost\n", __FUNCTION__, new_len);
1263 goto done;
1264 }
1265 skb = __dev_alloc_skb(new_len+4, GFP_ATOMIC);
1266
1267 if (!skb) {
1268 printk(KERN_INFO
1269 "ctcm: %s Out of memory in "
1270 "%s()- request-len:%04x \n",
1271 dev->name,
1272 __FUNCTION__,
1273 new_len+4);
1274 priv->stats.rx_dropped++;
1275 fsm_event(grp->fsm,
1276 MPCG_EVENT_INOP, dev);
1277 goto done;
1278 }
1279
1280 memcpy(skb_put(skb, new_len),
1281 pskb->data, new_len);
1282
1283 skb_reset_mac_header(skb);
1284 skb->dev = pskb->dev;
1285 skb->protocol = pskb->protocol;
1286 skb->ip_summed = CHECKSUM_UNNECESSARY;
1287 *((__u32 *) skb_push(skb, 4)) = ch->pdu_seq;
1288 ch->pdu_seq++;
1289
1290 if (do_debug_data)
1291 ctcm_pr_debug("%s: ToDCM_pdu_seq= %08x\n",
1292 __FUNCTION__, ch->pdu_seq);
1293
1294 ctcm_pr_debug("ctcm: %s() skb:%0lx "
1295 "skb len: %d \n", __FUNCTION__,
1296 (unsigned long)skb, skb->len);
1297 if (do_debug_data) {
1298 ctcm_pr_debug("ctcmpc: %s() up to 32 bytes"
1299 " of pdu_data sent\n",
1300 __FUNCTION__);
1301 ctcmpc_dump32((char *)skb->data, skb->len);
1302 }
1303
1304 skblen = skb->len;
1305 sendrc = netif_rx(skb);
1306 priv->stats.rx_packets++;
1307 priv->stats.rx_bytes += skblen;
1308 skb_pull(pskb, new_len); /* point to next PDU */
1309 }
1310 } else {
1311 mpcginfo = (struct mpcg_info *)
1312 kmalloc(sizeof(struct mpcg_info), gfp_type());
1313 if (mpcginfo == NULL)
1314 goto done;
1315
1316 mpcginfo->ch = ch;
1317 mpcginfo->th = header;
1318 mpcginfo->skb = pskb;
1319 ctcm_pr_debug("ctcmpc: %s() Not PDU - may be control pkt\n",
1320 __FUNCTION__);
1321 /* it's a sweep? */
1322 sweep = (struct th_sweep *)pskb->data;
1323 mpcginfo->sweep = sweep;
1324 if (header->th_ch_flag == TH_SWEEP_REQ)
1325 mpc_rcvd_sweep_req(mpcginfo);
1326 else if (header->th_ch_flag == TH_SWEEP_RESP)
1327 mpc_rcvd_sweep_resp(mpcginfo);
1328 else if (header->th_blk_flag == TH_DATA_IS_XID) {
1329 struct xid2 *thisxid = (struct xid2 *)pskb->data;
1330 skb_pull(pskb, XID2_LENGTH);
1331 mpcginfo->xid = thisxid;
1332 fsm_event(grp->fsm, MPCG_EVENT_XID2, mpcginfo);
1333 } else if (header->th_blk_flag == TH_DISCONTACT)
1334 fsm_event(grp->fsm, MPCG_EVENT_DISCONC, mpcginfo);
1335 else if (header->th_seq_num != 0) {
1336 printk(KERN_INFO "%s unexpected packet"
1337 " expected control pkt\n", dev->name);
1338 priv->stats.rx_dropped++;
1339 /* mpcginfo only used for non-data transfers */
1340 kfree(mpcginfo);
1341 if (do_debug_data)
1342 ctcmpc_dump_skb(pskb, -8);
1343 }
1344 }
1345done:
1346
1347 dev_kfree_skb_any(pskb);
1348 if (sendrc == NET_RX_DROP) {
1349 printk(KERN_WARNING "%s %s() NETWORK BACKLOG EXCEEDED"
1350 " - PACKET DROPPED\n", dev->name, __FUNCTION__);
1351 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1352 }
1353
1354 if (do_debug)
1355 ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
1356 dev->name, __FUNCTION__, ch, ch->id);
1357}
1358
1359/**
1360 * tasklet helper for mpc's skb unpacking.
1361 *
1362 * ch The channel to work on.
1363 * Allow flow control back pressure to occur here.
1364 * Throttling back channel can result in excessive
1365 * channel inactivity and system deact of channel
1366 */
1367void ctcmpc_bh(unsigned long thischan)
1368{
1369 struct channel *ch = (struct channel *)thischan;
1370 struct sk_buff *skb;
1371 struct net_device *dev = ch->netdev;
1372 struct ctcm_priv *priv = dev->priv;
1373 struct mpc_group *grp = priv->mpcg;
1374
1375 if (do_debug)
1376 ctcm_pr_debug("%s cp:%i enter: %s() %s\n",
1377 dev->name, smp_processor_id(), __FUNCTION__, ch->id);
1378 /* caller has requested driver to throttle back */
1379 while ((fsm_getstate(grp->fsm) != MPCG_STATE_FLOWC) &&
1380 (skb = skb_dequeue(&ch->io_queue))) {
1381 ctcmpc_unpack_skb(ch, skb);
1382 if (grp->out_of_sequence > 20) {
1383 /* assume data loss has occurred if */
1384 /* missing seq_num for extended */
1385 /* period of time */
1386 grp->out_of_sequence = 0;
1387 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1388 break;
1389 }
1390 if (skb == skb_peek(&ch->io_queue))
1391 break;
1392 }
1393 if (do_debug)
1394 ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
1395 dev->name, __FUNCTION__, ch, ch->id);
1396 return;
1397}
1398
1399/*
1400 * MPC Group Initializations
1401 */
1402struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv)
1403{
1404 struct mpc_group *grp;
1405
1406 CTCM_DBF_TEXT(MPC_SETUP, 3, __FUNCTION__);
1407
1408 grp = kzalloc(sizeof(struct mpc_group), GFP_KERNEL);
1409 if (grp == NULL)
1410 return NULL;
1411
1412 grp->fsm =
1413 init_fsm("mpcg", mpcg_state_names, mpcg_event_names,
1414 MPCG_NR_STATES, MPCG_NR_EVENTS, mpcg_fsm,
1415 mpcg_fsm_len, GFP_KERNEL);
1416 if (grp->fsm == NULL) {
1417 kfree(grp);
1418 return NULL;
1419 }
1420
1421 fsm_newstate(grp->fsm, MPCG_STATE_RESET);
1422 fsm_settimer(grp->fsm, &grp->timer);
1423
1424 grp->xid_skb =
1425 __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC | GFP_DMA);
1426 if (grp->xid_skb == NULL) {
1427 printk(KERN_INFO "Couldn't alloc MPCgroup xid_skb\n");
1428 kfree_fsm(grp->fsm);
1429 kfree(grp);
1430 return NULL;
1431 }
1432 /* base xid for all channels in group */
1433 grp->xid_skb_data = grp->xid_skb->data;
1434 grp->xid_th = (struct th_header *)grp->xid_skb->data;
1435 memcpy(skb_put(grp->xid_skb, TH_HEADER_LENGTH),
1436 &thnorm, TH_HEADER_LENGTH);
1437
1438 grp->xid = (struct xid2 *) skb_tail_pointer(grp->xid_skb);
1439 memcpy(skb_put(grp->xid_skb, XID2_LENGTH), &init_xid, XID2_LENGTH);
1440 grp->xid->xid2_adj_id = jiffies | 0xfff00000;
1441 grp->xid->xid2_sender_id = jiffies;
1442
1443 grp->xid_id = skb_tail_pointer(grp->xid_skb);
1444 memcpy(skb_put(grp->xid_skb, 4), "VTAM", 4);
1445
1446 grp->rcvd_xid_skb =
1447 __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);
1448 if (grp->rcvd_xid_skb == NULL) {
1449 printk(KERN_INFO "Couldn't alloc MPCgroup rcvd_xid_skb\n");
1450 kfree_fsm(grp->fsm);
1451 dev_kfree_skb(grp->xid_skb);
1452 kfree(grp);
1453 return NULL;
1454 }
1455 grp->rcvd_xid_data = grp->rcvd_xid_skb->data;
1456 grp->rcvd_xid_th = (struct th_header *)grp->rcvd_xid_skb->data;
1457 memcpy(skb_put(grp->rcvd_xid_skb, TH_HEADER_LENGTH),
1458 &thnorm, TH_HEADER_LENGTH);
1459 grp->saved_xid2 = NULL;
1460 priv->xid = grp->xid;
1461 priv->mpcg = grp;
1462 return grp;
1463}
1464
1465/*
1466 * The MPC Group Station FSM
1467 */
1468
1469/*
1470 * MPC Group Station FSM actions
1471 * CTCM_PROTO_MPC only
1472 */
1473
1474/**
1475 * NOP action for statemachines
1476 */
1477static void mpc_action_nop(fsm_instance *fi, int event, void *arg)
1478{
1479}
1480
1481/*
1482 * invoked when the device transitions to dev_stopped
1483 * MPC will stop each individual channel if a single XID failure
1484 * occurs, or will intitiate all channels be stopped if a GROUP
1485 * level failure occurs.
1486 */
1487static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
1488{
1489 struct net_device *dev = arg;
1490 struct ctcm_priv *priv;
1491 struct mpc_group *grp;
1492 int rc = 0;
1493 struct channel *wch, *rch;
1494
1495 if (dev == NULL) {
1496 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
1497 return;
1498 }
1499
1500 ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__);
1501
1502 priv = dev->priv;
1503 grp = priv->mpcg;
1504 grp->flow_off_called = 0;
1505
1506 fsm_deltimer(&grp->timer);
1507
1508 if (grp->channels_terminating)
1509 goto done;
1510
1511 grp->channels_terminating = 1;
1512
1513 grp->saved_state = fsm_getstate(grp->fsm);
1514 fsm_newstate(grp->fsm, MPCG_STATE_INOP);
1515 if (grp->saved_state > MPCG_STATE_XID7INITF)
1516 printk(KERN_NOTICE "%s:MPC GROUP INOPERATIVE\n", dev->name);
1517 if ((grp->saved_state != MPCG_STATE_RESET) ||
1518 /* dealloc_channel has been called */
1519 ((grp->saved_state == MPCG_STATE_RESET) &&
1520 (grp->port_persist == 0)))
1521 fsm_deltimer(&priv->restart_timer);
1522
1523 wch = priv->channel[WRITE];
1524 rch = priv->channel[READ];
1525
1526 switch (grp->saved_state) {
1527 case MPCG_STATE_RESET:
1528 case MPCG_STATE_INOP:
1529 case MPCG_STATE_XID2INITW:
1530 case MPCG_STATE_XID0IOWAIT:
1531 case MPCG_STATE_XID2INITX:
1532 case MPCG_STATE_XID7INITW:
1533 case MPCG_STATE_XID7INITX:
1534 case MPCG_STATE_XID0IOWAIX:
1535 case MPCG_STATE_XID7INITI:
1536 case MPCG_STATE_XID7INITZ:
1537 case MPCG_STATE_XID7INITF:
1538 break;
1539 case MPCG_STATE_FLOWC:
1540 case MPCG_STATE_READY:
1541 default:
1542 tasklet_hi_schedule(&wch->ch_disc_tasklet);
1543 }
1544
1545 grp->xid2_tgnum = 0;
1546 grp->group_max_buflen = 0; /*min of all received */
1547 grp->outstanding_xid2 = 0;
1548 grp->outstanding_xid7 = 0;
1549 grp->outstanding_xid7_p2 = 0;
1550 grp->saved_xid2 = NULL;
1551 grp->xidnogood = 0;
1552 grp->changed_side = 0;
1553
1554 grp->rcvd_xid_skb->data = grp->rcvd_xid_data;
1555 skb_reset_tail_pointer(grp->rcvd_xid_skb);
1556 grp->rcvd_xid_skb->len = 0;
1557 grp->rcvd_xid_th = (struct th_header *)grp->rcvd_xid_skb->data;
1558 memcpy(skb_put(grp->rcvd_xid_skb, TH_HEADER_LENGTH), &thnorm,
1559 TH_HEADER_LENGTH);
1560
1561 if (grp->send_qllc_disc == 1) {
1562 grp->send_qllc_disc = 0;
1563 rc = mpc_send_qllc_discontact(dev);
1564 }
1565
1566 /* DO NOT issue DEV_EVENT_STOP directly out of this code */
1567 /* This can result in INOP of VTAM PU due to halting of */
1568 /* outstanding IO which causes a sense to be returned */
1569 /* Only about 3 senses are allowed and then IOS/VTAM will*/
1570 /* ebcome unreachable without manual intervention */
1571 if ((grp->port_persist == 1) || (grp->alloc_called)) {
1572 grp->alloc_called = 0;
1573 fsm_deltimer(&priv->restart_timer);
1574 fsm_addtimer(&priv->restart_timer,
1575 500,
1576 DEV_EVENT_RESTART,
1577 dev);
1578 fsm_newstate(grp->fsm, MPCG_STATE_RESET);
1579 if (grp->saved_state > MPCG_STATE_XID7INITF)
1580 printk(KERN_NOTICE "%s:MPC GROUP RECOVERY SCHEDULED\n",
1581 dev->name);
1582 } else {
1583 fsm_deltimer(&priv->restart_timer);
1584 fsm_addtimer(&priv->restart_timer, 500, DEV_EVENT_STOP, dev);
1585 fsm_newstate(grp->fsm, MPCG_STATE_RESET);
1586 printk(KERN_NOTICE "%s:MPC GROUP RECOVERY NOT ATTEMPTED\n",
1587 dev->name);
1588 }
1589
1590done:
1591 ctcm_pr_debug("ctcmpc exit:%s %s()\n", dev->name, __FUNCTION__);
1592 return;
1593}
1594
1595/**
1596 * Handle mpc group action timeout.
1597 * MPC Group Station FSM action
1598 * CTCM_PROTO_MPC only
1599 *
1600 * fi An instance of an mpc_group fsm.
1601 * event The event, just happened.
1602 * arg Generic pointer, casted from net_device * upon call.
1603 */
1604static void mpc_action_timeout(fsm_instance *fi, int event, void *arg)
1605{
1606 struct net_device *dev = arg;
1607 struct ctcm_priv *priv;
1608 struct mpc_group *grp;
1609 struct channel *wch;
1610 struct channel *rch;
1611
1612 CTCM_DBF_TEXT(MPC_TRACE, 6, __FUNCTION__);
1613
1614 if (dev == NULL) {
1615 CTCM_DBF_TEXT_(MPC_ERROR, 4, "%s: dev=NULL\n", __FUNCTION__);
1616 return;
1617 }
1618
1619 priv = dev->priv;
1620 grp = priv->mpcg;
1621 wch = priv->channel[WRITE];
1622 rch = priv->channel[READ];
1623
1624 switch (fsm_getstate(grp->fsm)) {
1625 case MPCG_STATE_XID2INITW:
1626 /* Unless there is outstanding IO on the */
1627 /* channel just return and wait for ATTN */
1628 /* interrupt to begin XID negotiations */
1629 if ((fsm_getstate(rch->fsm) == CH_XID0_PENDING) &&
1630 (fsm_getstate(wch->fsm) == CH_XID0_PENDING))
1631 break;
1632 default:
1633 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1634 }
1635
1636 CTCM_DBF_TEXT_(MPC_TRACE, 6, "%s: dev=%s exit",
1637 __FUNCTION__, dev->name);
1638 return;
1639}
1640
1641/*
1642 * MPC Group Station FSM action
1643 * CTCM_PROTO_MPC only
1644 */
1645void mpc_action_discontact(fsm_instance *fi, int event, void *arg)
1646{
1647 struct mpcg_info *mpcginfo = arg;
1648 struct channel *ch = mpcginfo->ch;
1649 struct net_device *dev = ch->netdev;
1650 struct ctcm_priv *priv = dev->priv;
1651 struct mpc_group *grp = priv->mpcg;
1652
1653 if (ch == NULL) {
1654 printk(KERN_INFO "%s() ch=NULL\n", __FUNCTION__);
1655 return;
1656 }
1657 if (ch->netdev == NULL) {
1658 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
1659 return;
1660 }
1661
1662 ctcm_pr_debug("ctcmpc enter: %s %s()\n", dev->name, __FUNCTION__);
1663
1664 grp->send_qllc_disc = 1;
1665 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
1666
1667 ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
1668 return;
1669}
1670
1671/*
1672 * MPC Group Station - not part of FSM
1673 * CTCM_PROTO_MPC only
1674 * called from add_channel in ctcm_main.c
1675 */
1676void mpc_action_send_discontact(unsigned long thischan)
1677{
1678 struct channel *ch;
1679 struct net_device *dev;
1680 struct ctcm_priv *priv;
1681 struct mpc_group *grp;
1682 int rc = 0;
1683 unsigned long saveflags;
1684
1685 ch = (struct channel *)thischan;
1686 dev = ch->netdev;
1687 priv = dev->priv;
1688 grp = priv->mpcg;
1689
1690 ctcm_pr_info("ctcmpc: %s cp:%i enter: %s() GrpState:%s ChState:%s\n",
1691 dev->name,
1692 smp_processor_id(),
1693 __FUNCTION__,
1694 fsm_getstate_str(grp->fsm),
1695 fsm_getstate_str(ch->fsm));
1696 saveflags = 0; /* avoids compiler warning with
1697 spin_unlock_irqrestore */
1698
1699 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
1700 rc = ccw_device_start(ch->cdev, &ch->ccw[15],
1701 (unsigned long)ch, 0xff, 0);
1702 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
1703
1704 if (rc != 0) {
1705 ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n",
1706 __FUNCTION__,
1707 ch->id);
1708 ctcm_ccw_check_rc(ch, rc, "send discontact");
1709 /* Not checking return code value here */
1710 /* Making best effort to notify partner*/
1711 /* that MPC Group is going down */
1712 }
1713
1714 ctcm_pr_debug("ctcmpc exit: %s %s()\n", dev->name, __FUNCTION__);
1715 return;
1716}
1717
1718
1719/*
1720 * helper function of mpc FSM
1721 * CTCM_PROTO_MPC only
1722 * mpc_action_rcvd_xid7
1723*/
1724static int mpc_validate_xid(struct mpcg_info *mpcginfo)
1725{
1726 struct channel *ch = mpcginfo->ch;
1727 struct net_device *dev = ch->netdev;
1728 struct ctcm_priv *priv = dev->priv;
1729 struct mpc_group *grp = priv->mpcg;
1730 struct xid2 *xid = mpcginfo->xid;
1731 int failed = 0;
1732 int rc = 0;
1733 __u64 our_id, their_id = 0;
1734 int len;
1735
1736 len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
1737
1738 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
1739
1740 if (mpcginfo->xid == NULL) {
1741 printk(KERN_INFO "%s() xid=NULL\n", __FUNCTION__);
1742 rc = 1;
1743 goto done;
1744 }
1745
1746 ctcm_pr_debug("ctcmpc : %s xid received()\n", __FUNCTION__);
1747 ctcmpc_dumpit((char *)mpcginfo->xid, XID2_LENGTH);
1748
1749 /*the received direction should be the opposite of ours */
1750 if (((CHANNEL_DIRECTION(ch->flags) == READ) ? XID2_WRITE_SIDE :
1751 XID2_READ_SIDE) != xid->xid2_dlc_type) {
1752 failed = 1;
1753 printk(KERN_INFO "ctcmpc:%s() XID REJECTED - READ-WRITE CH "
1754 "Pairing Invalid \n", __FUNCTION__);
1755 }
1756
1757 if (xid->xid2_dlc_type == XID2_READ_SIDE) {
1758 ctcm_pr_debug("ctcmpc: %s(): grpmaxbuf:%d xid2buflen:%d\n",
1759 __FUNCTION__, grp->group_max_buflen,
1760 xid->xid2_buf_len);
1761
1762 if (grp->group_max_buflen == 0 ||
1763 grp->group_max_buflen > xid->xid2_buf_len - len)
1764 grp->group_max_buflen = xid->xid2_buf_len - len;
1765 }
1766
1767
1768 if (grp->saved_xid2 == NULL) {
1769 grp->saved_xid2 =
1770 (struct xid2 *)skb_tail_pointer(grp->rcvd_xid_skb);
1771
1772 memcpy(skb_put(grp->rcvd_xid_skb,
1773 XID2_LENGTH), xid, XID2_LENGTH);
1774 grp->rcvd_xid_skb->data = grp->rcvd_xid_data;
1775
1776 skb_reset_tail_pointer(grp->rcvd_xid_skb);
1777 grp->rcvd_xid_skb->len = 0;
1778
1779 /* convert two 32 bit numbers into 1 64 bit for id compare */
1780 our_id = (__u64)priv->xid->xid2_adj_id;
1781 our_id = our_id << 32;
1782 our_id = our_id + priv->xid->xid2_sender_id;
1783 their_id = (__u64)xid->xid2_adj_id;
1784 their_id = their_id << 32;
1785 their_id = their_id + xid->xid2_sender_id;
1786 /* lower id assume the xside role */
1787 if (our_id < their_id) {
1788 grp->roll = XSIDE;
1789 ctcm_pr_debug("ctcmpc :%s() WE HAVE LOW ID-"
1790 "TAKE XSIDE\n", __FUNCTION__);
1791 } else {
1792 grp->roll = YSIDE;
1793 ctcm_pr_debug("ctcmpc :%s() WE HAVE HIGH ID-"
1794 "TAKE YSIDE\n", __FUNCTION__);
1795 }
1796
1797 } else {
1798 if (xid->xid2_flag4 != grp->saved_xid2->xid2_flag4) {
1799 failed = 1;
1800 printk(KERN_INFO "%s XID REJECTED - XID Flag Byte4\n",
1801 __FUNCTION__);
1802 }
1803 if (xid->xid2_flag2 == 0x40) {
1804 failed = 1;
1805 printk(KERN_INFO "%s XID REJECTED - XID NOGOOD\n",
1806 __FUNCTION__);
1807 }
1808 if (xid->xid2_adj_id != grp->saved_xid2->xid2_adj_id) {
1809 failed = 1;
1810 printk(KERN_INFO "%s XID REJECTED - "
1811 "Adjacent Station ID Mismatch\n",
1812 __FUNCTION__);
1813 }
1814 if (xid->xid2_sender_id != grp->saved_xid2->xid2_sender_id) {
1815 failed = 1;
1816 printk(KERN_INFO "%s XID REJECTED - "
1817 "Sender Address Mismatch\n", __FUNCTION__);
1818
1819 }
1820 }
1821
1822 if (failed) {
1823 ctcm_pr_info("ctcmpc : %s() failed\n", __FUNCTION__);
1824 priv->xid->xid2_flag2 = 0x40;
1825 grp->saved_xid2->xid2_flag2 = 0x40;
1826 rc = 1;
1827 }
1828
1829done:
1830
1831 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
1832 return rc;
1833}
1834
1835/*
1836 * MPC Group Station FSM action
1837 * CTCM_PROTO_MPC only
1838 */
1839static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
1840{
1841 struct channel *ch = arg;
1842 struct ctcm_priv *priv;
1843 struct mpc_group *grp = NULL;
1844 struct net_device *dev = NULL;
1845 int rc = 0;
1846 int gotlock = 0;
1847 unsigned long saveflags = 0; /* avoids compiler warning with
1848 spin_unlock_irqrestore */
1849
1850 if (ch == NULL) {
1851 printk(KERN_INFO "%s ch=NULL\n", __FUNCTION__);
1852 goto done;
1853 }
1854
1855 if (do_debug)
1856 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
1857 __FUNCTION__, smp_processor_id(), ch, ch->id);
1858
1859 dev = ch->netdev;
1860 if (dev == NULL) {
1861 printk(KERN_INFO "%s dev=NULL\n", __FUNCTION__);
1862 goto done;
1863 }
1864
1865 priv = dev->priv;
1866 if (priv == NULL) {
1867 printk(KERN_INFO "%s priv=NULL\n", __FUNCTION__);
1868 goto done;
1869 }
1870
1871 grp = priv->mpcg;
1872 if (grp == NULL) {
1873 printk(KERN_INFO "%s grp=NULL\n", __FUNCTION__);
1874 goto done;
1875 }
1876
1877 if (ctcm_checkalloc_buffer(ch))
1878 goto done;
1879
1880 /* skb data-buffer referencing: */
1881
1882 ch->trans_skb->data = ch->trans_skb_data;
1883 skb_reset_tail_pointer(ch->trans_skb);
1884 ch->trans_skb->len = 0;
1885 /* result of the previous 3 statements is NOT always
1886 * already set after ctcm_checkalloc_buffer
1887 * because of possible reuse of the trans_skb
1888 */
1889 memset(ch->trans_skb->data, 0, 16);
1890 ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data;
1891 /* check is main purpose here: */
1892 skb_put(ch->trans_skb, TH_HEADER_LENGTH);
1893 ch->rcvd_xid = (struct xid2 *)skb_tail_pointer(ch->trans_skb);
1894 /* check is main purpose here: */
1895 skb_put(ch->trans_skb, XID2_LENGTH);
1896 ch->rcvd_xid_id = skb_tail_pointer(ch->trans_skb);
1897 /* cleanup back to startpoint */
1898 ch->trans_skb->data = ch->trans_skb_data;
1899 skb_reset_tail_pointer(ch->trans_skb);
1900 ch->trans_skb->len = 0;
1901
1902 /* non-checking rewrite of above skb data-buffer referencing: */
1903 /*
1904 memset(ch->trans_skb->data, 0, 16);
1905 ch->rcvd_xid_th = (struct th_header *)ch->trans_skb_data;
1906 ch->rcvd_xid = (struct xid2 *)(ch->trans_skb_data + TH_HEADER_LENGTH);
1907 ch->rcvd_xid_id = ch->trans_skb_data + TH_HEADER_LENGTH + XID2_LENGTH;
1908 */
1909
1910 ch->ccw[8].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1911 ch->ccw[8].count = 0;
1912 ch->ccw[8].cda = 0x00;
1913
1914 if (side == XSIDE) {
1915 /* mpc_action_xside_xid */
1916 if (ch->xid_th == NULL) {
1917 printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__);
1918 goto done;
1919 }
1920 ch->ccw[9].cmd_code = CCW_CMD_WRITE;
1921 ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1922 ch->ccw[9].count = TH_HEADER_LENGTH;
1923 ch->ccw[9].cda = virt_to_phys(ch->xid_th);
1924
1925 if (ch->xid == NULL) {
1926 printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__);
1927 goto done;
1928 }
1929
1930 ch->ccw[10].cmd_code = CCW_CMD_WRITE;
1931 ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1932 ch->ccw[10].count = XID2_LENGTH;
1933 ch->ccw[10].cda = virt_to_phys(ch->xid);
1934
1935 ch->ccw[11].cmd_code = CCW_CMD_READ;
1936 ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1937 ch->ccw[11].count = TH_HEADER_LENGTH;
1938 ch->ccw[11].cda = virt_to_phys(ch->rcvd_xid_th);
1939
1940 ch->ccw[12].cmd_code = CCW_CMD_READ;
1941 ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1942 ch->ccw[12].count = XID2_LENGTH;
1943 ch->ccw[12].cda = virt_to_phys(ch->rcvd_xid);
1944
1945 ch->ccw[13].cmd_code = CCW_CMD_READ;
1946 ch->ccw[13].cda = virt_to_phys(ch->rcvd_xid_id);
1947
1948 } else { /* side == YSIDE : mpc_action_yside_xid */
1949 ch->ccw[9].cmd_code = CCW_CMD_READ;
1950 ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1951 ch->ccw[9].count = TH_HEADER_LENGTH;
1952 ch->ccw[9].cda = virt_to_phys(ch->rcvd_xid_th);
1953
1954 ch->ccw[10].cmd_code = CCW_CMD_READ;
1955 ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1956 ch->ccw[10].count = XID2_LENGTH;
1957 ch->ccw[10].cda = virt_to_phys(ch->rcvd_xid);
1958
1959 if (ch->xid_th == NULL) {
1960 printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__);
1961 goto done;
1962 }
1963 ch->ccw[11].cmd_code = CCW_CMD_WRITE;
1964 ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1965 ch->ccw[11].count = TH_HEADER_LENGTH;
1966 ch->ccw[11].cda = virt_to_phys(ch->xid_th);
1967
1968 if (ch->xid == NULL) {
1969 printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__);
1970 goto done;
1971 }
1972 ch->ccw[12].cmd_code = CCW_CMD_WRITE;
1973 ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1974 ch->ccw[12].count = XID2_LENGTH;
1975 ch->ccw[12].cda = virt_to_phys(ch->xid);
1976
1977 if (ch->xid_id == NULL) {
1978 printk(KERN_INFO "%s ch->xid_id=NULL\n", __FUNCTION__);
1979 goto done;
1980 }
1981 ch->ccw[13].cmd_code = CCW_CMD_WRITE;
1982 ch->ccw[13].cda = virt_to_phys(ch->xid_id);
1983
1984 }
1985 ch->ccw[13].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1986 ch->ccw[13].count = 4;
1987
1988 ch->ccw[14].cmd_code = CCW_CMD_NOOP;
1989 ch->ccw[14].flags = CCW_FLAG_SLI;
1990 ch->ccw[14].count = 0;
1991 ch->ccw[14].cda = 0;
1992
1993 if (do_debug_ccw)
1994 ctcmpc_dumpit((char *)&ch->ccw[8], sizeof(struct ccw1) * 7);
1995
1996 ctcmpc_dumpit((char *)ch->xid_th, TH_HEADER_LENGTH);
1997 ctcmpc_dumpit((char *)ch->xid, XID2_LENGTH);
1998 ctcmpc_dumpit((char *)ch->xid_id, 4);
1999 if (!in_irq()) {
2000 /* Such conditional locking is a known problem for
2001 * sparse because its static undeterministic.
2002 * Warnings should be ignored here. */
2003 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
2004 gotlock = 1;
2005 }
2006
2007 fsm_addtimer(&ch->timer, 5000 , CTC_EVENT_TIMER, ch);
2008 rc = ccw_device_start(ch->cdev, &ch->ccw[8],
2009 (unsigned long)ch, 0xff, 0);
2010
2011 if (gotlock) /* see remark above about conditional locking */
2012 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
2013
2014 if (rc != 0) {
2015 ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n",
2016 __FUNCTION__, ch->id);
2017 ctcm_ccw_check_rc(ch, rc,
2018 (side == XSIDE) ? "x-side XID" : "y-side XID");
2019 }
2020
2021done:
2022 if (do_debug)
2023 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
2024 __FUNCTION__, ch, ch->id);
2025 return;
2026
2027}
2028
2029/*
2030 * MPC Group Station FSM action
2031 * CTCM_PROTO_MPC only
2032 */
2033static void mpc_action_xside_xid(fsm_instance *fsm, int event, void *arg)
2034{
2035 mpc_action_side_xid(fsm, arg, XSIDE);
2036}
2037
2038/*
2039 * MPC Group Station FSM action
2040 * CTCM_PROTO_MPC only
2041 */
2042static void mpc_action_yside_xid(fsm_instance *fsm, int event, void *arg)
2043{
2044 mpc_action_side_xid(fsm, arg, YSIDE);
2045}
2046
2047/*
2048 * MPC Group Station FSM action
2049 * CTCM_PROTO_MPC only
2050 */
2051static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg)
2052{
2053 struct channel *ch = arg;
2054 struct ctcm_priv *priv;
2055 struct mpc_group *grp = NULL;
2056 struct net_device *dev = NULL;
2057
2058 if (do_debug)
2059 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
2060 __FUNCTION__, smp_processor_id(), ch, ch->id);
2061
2062 if (ch == NULL) {
2063 printk(KERN_WARNING "%s ch=NULL\n", __FUNCTION__);
2064 goto done;
2065 }
2066
2067 dev = ch->netdev;
2068 if (dev == NULL) {
2069 printk(KERN_WARNING "%s dev=NULL\n", __FUNCTION__);
2070 goto done;
2071 }
2072
2073 priv = dev->priv;
2074 if (priv == NULL) {
2075 printk(KERN_WARNING "%s priv=NULL\n", __FUNCTION__);
2076 goto done;
2077 }
2078
2079 grp = priv->mpcg;
2080 if (grp == NULL) {
2081 printk(KERN_WARNING "%s grp=NULL\n", __FUNCTION__);
2082 goto done;
2083 }
2084
2085 if (ch->xid == NULL) {
2086 printk(KERN_WARNING "%s ch-xid=NULL\n", __FUNCTION__);
2087 goto done;
2088 }
2089
2090 fsm_newstate(ch->fsm, CH_XID0_INPROGRESS);
2091
2092 ch->xid->xid2_option = XID2_0;
2093
2094 switch (fsm_getstate(grp->fsm)) {
2095 case MPCG_STATE_XID2INITW:
2096 case MPCG_STATE_XID2INITX:
2097 ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD;
2098 break;
2099 case MPCG_STATE_XID0IOWAIT:
2100 case MPCG_STATE_XID0IOWAIX:
2101 ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL;
2102 break;
2103 }
2104
2105 fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch);
2106
2107done:
2108 if (do_debug)
2109 ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
2110 __FUNCTION__, ch, ch->id);
2111 return;
2112
2113}
2114
2115/*
2116 * MPC Group Station FSM action
2117 * CTCM_PROTO_MPC only
2118*/
2119static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg)
2120{
2121 struct net_device *dev = arg;
2122 struct ctcm_priv *priv = NULL;
2123 struct mpc_group *grp = NULL;
2124 int direction;
2125 int rc = 0;
2126 int send = 0;
2127
2128 ctcm_pr_debug("ctcmpc enter: %s() \n", __FUNCTION__);
2129
2130 if (dev == NULL) {
2131 printk(KERN_INFO "%s dev=NULL \n", __FUNCTION__);
2132 rc = 1;
2133 goto done;
2134 }
2135
2136 priv = dev->priv;
2137 if (priv == NULL) {
2138 printk(KERN_INFO "%s priv=NULL \n", __FUNCTION__);
2139 rc = 1;
2140 goto done;
2141 }
2142
2143 grp = priv->mpcg;
2144 if (grp == NULL) {
2145 printk(KERN_INFO "%s grp=NULL \n", __FUNCTION__);
2146 rc = 1;
2147 goto done;
2148 }
2149
2150 for (direction = READ; direction <= WRITE; direction++) {
2151 struct channel *ch = priv->channel[direction];
2152 struct xid2 *thisxid = ch->xid;
2153 ch->xid_skb->data = ch->xid_skb_data;
2154 skb_reset_tail_pointer(ch->xid_skb);
2155 ch->xid_skb->len = 0;
2156 thisxid->xid2_option = XID2_7;
2157 send = 0;
2158
2159 /* xid7 phase 1 */
2160 if (grp->outstanding_xid7_p2 > 0) {
2161 if (grp->roll == YSIDE) {
2162 if (fsm_getstate(ch->fsm) == CH_XID7_PENDING1) {
2163 fsm_newstate(ch->fsm, CH_XID7_PENDING2);
2164 ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD;
2165 memcpy(skb_put(ch->xid_skb,
2166 TH_HEADER_LENGTH),
2167 &thdummy, TH_HEADER_LENGTH);
2168 send = 1;
2169 }
2170 } else if (fsm_getstate(ch->fsm) < CH_XID7_PENDING2) {
2171 fsm_newstate(ch->fsm, CH_XID7_PENDING2);
2172 ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL;
2173 memcpy(skb_put(ch->xid_skb,
2174 TH_HEADER_LENGTH),
2175 &thnorm, TH_HEADER_LENGTH);
2176 send = 1;
2177 }
2178 } else {
2179 /* xid7 phase 2 */
2180 if (grp->roll == YSIDE) {
2181 if (fsm_getstate(ch->fsm) < CH_XID7_PENDING4) {
2182 fsm_newstate(ch->fsm, CH_XID7_PENDING4);
2183 memcpy(skb_put(ch->xid_skb,
2184 TH_HEADER_LENGTH),
2185 &thnorm, TH_HEADER_LENGTH);
2186 ch->ccw[8].cmd_code = CCW_CMD_WRITE_CTL;
2187 send = 1;
2188 }
2189 } else if (fsm_getstate(ch->fsm) == CH_XID7_PENDING3) {
2190 fsm_newstate(ch->fsm, CH_XID7_PENDING4);
2191 ch->ccw[8].cmd_code = CCW_CMD_SENSE_CMD;
2192 memcpy(skb_put(ch->xid_skb, TH_HEADER_LENGTH),
2193 &thdummy, TH_HEADER_LENGTH);
2194 send = 1;
2195 }
2196 }
2197
2198 if (send)
2199 fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch);
2200 }
2201
2202done:
2203
2204 if (rc != 0)
2205 fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
2206
2207 return;
2208}
2209
2210/*
2211 * MPC Group Station FSM action
2212 * CTCM_PROTO_MPC only
2213 */
2214static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg)
2215{
2216
2217 struct mpcg_info *mpcginfo = arg;
2218 struct channel *ch = mpcginfo->ch;
2219 struct net_device *dev = ch->netdev;
2220 struct ctcm_priv *priv;
2221 struct mpc_group *grp;
2222
2223 if (do_debug)
2224 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
2225 __FUNCTION__, smp_processor_id(), ch, ch->id);
2226
2227 priv = dev->priv;
2228 grp = priv->mpcg;
2229
2230 ctcm_pr_debug("ctcmpc in:%s() %s xid2:%i xid7:%i xidt_p2:%i \n",
2231 __FUNCTION__, ch->id,
2232 grp->outstanding_xid2,
2233 grp->outstanding_xid7,
2234 grp->outstanding_xid7_p2);
2235
2236 if (fsm_getstate(ch->fsm) < CH_XID7_PENDING)
2237 fsm_newstate(ch->fsm, CH_XID7_PENDING);
2238
2239 grp->outstanding_xid2--;
2240 grp->outstanding_xid7++;
2241 grp->outstanding_xid7_p2++;
2242
2243 /* must change state before validating xid to */
2244 /* properly handle interim interrupts received*/
2245 switch (fsm_getstate(grp->fsm)) {
2246 case MPCG_STATE_XID2INITW:
2247 fsm_newstate(grp->fsm, MPCG_STATE_XID2INITX);
2248 mpc_validate_xid(mpcginfo);
2249 break;
2250 case MPCG_STATE_XID0IOWAIT:
2251 fsm_newstate(grp->fsm, MPCG_STATE_XID0IOWAIX);
2252 mpc_validate_xid(mpcginfo);
2253 break;
2254 case MPCG_STATE_XID2INITX:
2255 if (grp->outstanding_xid2 == 0) {
2256 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITW);
2257 mpc_validate_xid(mpcginfo);
2258 fsm_event(grp->fsm, MPCG_EVENT_XID2DONE, dev);
2259 }
2260 break;
2261 case MPCG_STATE_XID0IOWAIX:
2262 if (grp->outstanding_xid2 == 0) {
2263 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITI);
2264 mpc_validate_xid(mpcginfo);
2265 fsm_event(grp->fsm, MPCG_EVENT_XID2DONE, dev);
2266 }
2267 break;
2268 }
2269 kfree(mpcginfo);
2270
2271 if (do_debug) {
2272 ctcm_pr_debug("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n",
2273 __FUNCTION__, ch->id,
2274 grp->outstanding_xid2,
2275 grp->outstanding_xid7,
2276 grp->outstanding_xid7_p2);
2277 ctcm_pr_debug("ctcmpc:%s() %s grpstate: %s chanstate: %s \n",
2278 __FUNCTION__, ch->id,
2279 fsm_getstate_str(grp->fsm),
2280 fsm_getstate_str(ch->fsm));
2281 }
2282 return;
2283
2284}
2285
2286
2287/*
2288 * MPC Group Station FSM action
2289 * CTCM_PROTO_MPC only
2290 */
2291static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg)
2292{
2293 struct mpcg_info *mpcginfo = arg;
2294 struct channel *ch = mpcginfo->ch;
2295 struct net_device *dev = ch->netdev;
2296 struct ctcm_priv *priv = dev->priv;
2297 struct mpc_group *grp = priv->mpcg;
2298
2299 if (do_debug) {
2300 ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
2301 __FUNCTION__, smp_processor_id(), ch, ch->id);
2302
2303 ctcm_pr_debug("ctcmpc: outstanding_xid7: %i, "
2304 " outstanding_xid7_p2: %i\n",
2305 grp->outstanding_xid7,
2306 grp->outstanding_xid7_p2);
2307 }
2308
2309 grp->outstanding_xid7--;
2310 ch->xid_skb->data = ch->xid_skb_data;
2311 skb_reset_tail_pointer(ch->xid_skb);
2312 ch->xid_skb->len = 0;
2313
2314 switch (fsm_getstate(grp->fsm)) {
2315 case MPCG_STATE_XID7INITI:
2316 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITZ);
2317 mpc_validate_xid(mpcginfo);
2318 break;
2319 case MPCG_STATE_XID7INITW:
2320 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITX);
2321 mpc_validate_xid(mpcginfo);
2322 break;
2323 case MPCG_STATE_XID7INITZ:
2324 case MPCG_STATE_XID7INITX:
2325 if (grp->outstanding_xid7 == 0) {
2326 if (grp->outstanding_xid7_p2 > 0) {
2327 grp->outstanding_xid7 =
2328 grp->outstanding_xid7_p2;
2329 grp->outstanding_xid7_p2 = 0;
2330 } else
2331 fsm_newstate(grp->fsm, MPCG_STATE_XID7INITF);
2332
2333 mpc_validate_xid(mpcginfo);
2334 fsm_event(grp->fsm, MPCG_EVENT_XID7DONE, dev);
2335 break;
2336 }
2337 mpc_validate_xid(mpcginfo);
2338 break;
2339 }
2340
2341 kfree(mpcginfo);
2342
2343 if (do_debug)
2344 ctcm_pr_debug("ctcmpc exit: %s(): cp=%i ch=0x%p id=%s\n",
2345 __FUNCTION__, smp_processor_id(), ch, ch->id);
2346 return;
2347
2348}
2349
2350/*
2351 * mpc_action helper of an MPC Group Station FSM action
2352 * CTCM_PROTO_MPC only
2353 */
2354static int mpc_send_qllc_discontact(struct net_device *dev)
2355{
2356 int rc = 0;
2357 __u32 new_len = 0;
2358 struct sk_buff *skb;
2359 struct qllc *qllcptr;
2360 struct ctcm_priv *priv;
2361 struct mpc_group *grp;
2362
2363 ctcm_pr_debug("ctcmpc enter: %s()\n", __FUNCTION__);
2364
2365 if (dev == NULL) {
2366 printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
2367 rc = 1;
2368 goto done;
2369 }
2370
2371 priv = dev->priv;
2372 if (priv == NULL) {
2373 printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
2374 rc = 1;
2375 goto done;
2376 }
2377
2378 grp = priv->mpcg;
2379 if (grp == NULL) {
2380 printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__);
2381 rc = 1;
2382 goto done;
2383 }
2384 ctcm_pr_info("ctcmpc: %s() GROUP STATE: %s\n", __FUNCTION__,
2385 mpcg_state_names[grp->saved_state]);
2386
2387 switch (grp->saved_state) {
2388 /*
2389 * establish conn callback function is
2390 * preferred method to report failure
2391 */
2392 case MPCG_STATE_XID0IOWAIT:
2393 case MPCG_STATE_XID0IOWAIX:
2394 case MPCG_STATE_XID7INITI:
2395 case MPCG_STATE_XID7INITZ:
2396 case MPCG_STATE_XID2INITW:
2397 case MPCG_STATE_XID2INITX:
2398 case MPCG_STATE_XID7INITW:
2399 case MPCG_STATE_XID7INITX:
2400 if (grp->estconnfunc) {
2401 grp->estconnfunc(grp->port_num, -1, 0);
2402 grp->estconnfunc = NULL;
2403 break;
2404 }
2405 case MPCG_STATE_FLOWC:
2406 case MPCG_STATE_READY:
2407 grp->send_qllc_disc = 2;
2408 new_len = sizeof(struct qllc);
2409 qllcptr = kzalloc(new_len, gfp_type() | GFP_DMA);
2410 if (qllcptr == NULL) {
2411 printk(KERN_INFO
2412 "ctcmpc: Out of memory in %s()\n",
2413 dev->name);
2414 rc = 1;
2415 goto done;
2416 }
2417
2418 qllcptr->qllc_address = 0xcc;
2419 qllcptr->qllc_commands = 0x03;
2420
2421 skb = __dev_alloc_skb(new_len, GFP_ATOMIC);
2422
2423 if (skb == NULL) {
2424 printk(KERN_INFO "%s Out of memory in mpc_send_qllc\n",
2425 dev->name);
2426 priv->stats.rx_dropped++;
2427 rc = 1;
2428 kfree(qllcptr);
2429 goto done;
2430 }
2431
2432 memcpy(skb_put(skb, new_len), qllcptr, new_len);
2433 kfree(qllcptr);
2434
2435 if (skb_headroom(skb) < 4) {
2436 printk(KERN_INFO "ctcmpc: %s() Unable to"
2437 " build discontact for %s\n",
2438 __FUNCTION__, dev->name);
2439 rc = 1;
2440 dev_kfree_skb_any(skb);
2441 goto done;
2442 }
2443
2444 *((__u32 *)skb_push(skb, 4)) = priv->channel[READ]->pdu_seq;
2445 priv->channel[READ]->pdu_seq++;
2446 if (do_debug_data)
2447 ctcm_pr_debug("ctcmpc: %s ToDCM_pdu_seq= %08x\n",
2448 __FUNCTION__, priv->channel[READ]->pdu_seq);
2449
2450 /* receipt of CC03 resets anticipated sequence number on
2451 receiving side */
2452 priv->channel[READ]->pdu_seq = 0x00;
2453 skb_reset_mac_header(skb);
2454 skb->dev = dev;
2455 skb->protocol = htons(ETH_P_SNAP);
2456 skb->ip_summed = CHECKSUM_UNNECESSARY;
2457
2458 ctcmpc_dumpit((char *)skb->data, (sizeof(struct qllc) + 4));
2459
2460 netif_rx(skb);
2461 break;
2462 default:
2463 break;
2464
2465 }
2466
2467done:
2468 ctcm_pr_debug("ctcmpc exit: %s()\n", __FUNCTION__);
2469 return rc;
2470}
2471/* --- This is the END my friend --- */
2472
diff --git a/drivers/s390/net/ctcm_mpc.h b/drivers/s390/net/ctcm_mpc.h
new file mode 100644
index 000000000000..f99686069a91
--- /dev/null
+++ b/drivers/s390/net/ctcm_mpc.h
@@ -0,0 +1,239 @@
1/*
2 * drivers/s390/net/ctcm_mpc.h
3 *
4 * Copyright IBM Corp. 2007
5 * Authors: Peter Tiedemann (ptiedem@de.ibm.com)
6 *
7 * MPC additions:
8 * Belinda Thompson (belindat@us.ibm.com)
9 * Andy Richter (richtera@us.ibm.com)
10 */
11
12#ifndef _CTC_MPC_H_
13#define _CTC_MPC_H_
14
15#include <linux/skbuff.h>
16#include "fsm.h"
17
18/*
19 * MPC external interface
20 * Note that ctc_mpc_xyz are called with a lock on ................
21 */
22
23/* port_number is the mpc device 0, 1, 2 etc mpc2 is port_number 2 */
24
25/* passive open Just wait for XID2 exchange */
26extern int ctc_mpc_alloc_channel(int port,
27 void (*callback)(int port_num, int max_write_size));
28/* active open Alloc then send XID2 */
29extern void ctc_mpc_establish_connectivity(int port,
30 void (*callback)(int port_num, int rc, int max_write_size));
31
32extern void ctc_mpc_dealloc_ch(int port);
33extern void ctc_mpc_flow_control(int port, int flowc);
34
35/*
36 * other MPC Group prototypes and structures
37 */
38
39#define ETH_P_SNA_DIX 0x80D5
40
41/*
42 * Declaration of an XID2
43 *
44 */
45#define ALLZEROS 0x0000000000000000
46
47#define XID_FM2 0x20
48#define XID2_0 0x00
49#define XID2_7 0x07
50#define XID2_WRITE_SIDE 0x04
51#define XID2_READ_SIDE 0x05
52
53struct xid2 {
54 __u8 xid2_type_id;
55 __u8 xid2_len;
56 __u32 xid2_adj_id;
57 __u8 xid2_rlen;
58 __u8 xid2_resv1;
59 __u8 xid2_flag1;
60 __u8 xid2_fmtt;
61 __u8 xid2_flag4;
62 __u16 xid2_resv2;
63 __u8 xid2_tgnum;
64 __u32 xid2_sender_id;
65 __u8 xid2_flag2;
66 __u8 xid2_option;
67 char xid2_resv3[8];
68 __u16 xid2_resv4;
69 __u8 xid2_dlc_type;
70 __u16 xid2_resv5;
71 __u8 xid2_mpc_flag;
72 __u8 xid2_resv6;
73 __u16 xid2_buf_len;
74 char xid2_buffer[255 - (13 * sizeof(__u8) +
75 2 * sizeof(__u32) +
76 4 * sizeof(__u16) +
77 8 * sizeof(char))];
78} __attribute__ ((packed));
79
80#define XID2_LENGTH (sizeof(struct xid2))
81
82struct th_header {
83 __u8 th_seg;
84 __u8 th_ch_flag;
85#define TH_HAS_PDU 0xf0
86#define TH_IS_XID 0x01
87#define TH_SWEEP_REQ 0xfe
88#define TH_SWEEP_RESP 0xff
89 __u8 th_blk_flag;
90#define TH_DATA_IS_XID 0x80
91#define TH_RETRY 0x40
92#define TH_DISCONTACT 0xc0
93#define TH_SEG_BLK 0x20
94#define TH_LAST_SEG 0x10
95#define TH_PDU_PART 0x08
96 __u8 th_is_xid; /* is 0x01 if this is XID */
97 __u32 th_seq_num;
98} __attribute__ ((packed));
99
100struct th_addon {
101 __u32 th_last_seq;
102 __u32 th_resvd;
103} __attribute__ ((packed));
104
105struct th_sweep {
106 struct th_header th;
107 struct th_addon sw;
108} __attribute__ ((packed));
109
110#define TH_HEADER_LENGTH (sizeof(struct th_header))
111#define TH_SWEEP_LENGTH (sizeof(struct th_sweep))
112
113#define PDU_LAST 0x80
114#define PDU_CNTL 0x40
115#define PDU_FIRST 0x20
116
117struct pdu {
118 __u32 pdu_offset;
119 __u8 pdu_flag;
120 __u8 pdu_proto; /* 0x01 is APPN SNA */
121 __u16 pdu_seq;
122} __attribute__ ((packed));
123
124#define PDU_HEADER_LENGTH (sizeof(struct pdu))
125
126struct qllc {
127 __u8 qllc_address;
128#define QLLC_REQ 0xFF
129#define QLLC_RESP 0x00
130 __u8 qllc_commands;
131#define QLLC_DISCONNECT 0x53
132#define QLLC_UNSEQACK 0x73
133#define QLLC_SETMODE 0x93
134#define QLLC_EXCHID 0xBF
135} __attribute__ ((packed));
136
137
138/*
139 * Definition of one MPC group
140 */
141
142#define MAX_MPCGCHAN 10
143#define MPC_XID_TIMEOUT_VALUE 10000
144#define MPC_CHANNEL_ADD 0
145#define MPC_CHANNEL_REMOVE 1
146#define MPC_CHANNEL_ATTN 2
147#define XSIDE 1
148#define YSIDE 0
149
150struct mpcg_info {
151 struct sk_buff *skb;
152 struct channel *ch;
153 struct xid2 *xid;
154 struct th_sweep *sweep;
155 struct th_header *th;
156};
157
158struct mpc_group {
159 struct tasklet_struct mpc_tasklet;
160 struct tasklet_struct mpc_tasklet2;
161 int changed_side;
162 int saved_state;
163 int channels_terminating;
164 int out_of_sequence;
165 int flow_off_called;
166 int port_num;
167 int port_persist;
168 int alloc_called;
169 __u32 xid2_adj_id;
170 __u8 xid2_tgnum;
171 __u32 xid2_sender_id;
172 int num_channel_paths;
173 int active_channels[2];
174 __u16 group_max_buflen;
175 int outstanding_xid2;
176 int outstanding_xid7;
177 int outstanding_xid7_p2;
178 int sweep_req_pend_num;
179 int sweep_rsp_pend_num;
180 struct sk_buff *xid_skb;
181 char *xid_skb_data;
182 struct th_header *xid_th;
183 struct xid2 *xid;
184 char *xid_id;
185 struct th_header *rcvd_xid_th;
186 struct sk_buff *rcvd_xid_skb;
187 char *rcvd_xid_data;
188 __u8 in_sweep;
189 __u8 roll;
190 struct xid2 *saved_xid2;
191 void (*allochanfunc)(int, int);
192 int allocchan_callback_retries;
193 void (*estconnfunc)(int, int, int);
194 int estconn_callback_retries;
195 int estconn_called;
196 int xidnogood;
197 int send_qllc_disc;
198 fsm_timer timer;
199 fsm_instance *fsm; /* group xid fsm */
200};
201
202#ifdef DEBUGDATA
203void ctcmpc_dumpit(char *buf, int len);
204#else
205static inline void ctcmpc_dumpit(char *buf, int len)
206{
207}
208#endif
209
210#ifdef DEBUGDATA
211/*
212 * Dump header and first 16 bytes of an sk_buff for debugging purposes.
213 *
214 * skb The struct sk_buff to dump.
215 * offset Offset relative to skb-data, where to start the dump.
216 */
217void ctcmpc_dump_skb(struct sk_buff *skb, int offset);
218#else
219static inline void ctcmpc_dump_skb(struct sk_buff *skb, int offset)
220{}
221#endif
222
223static inline void ctcmpc_dump32(char *buf, int len)
224{
225 if (len < 32)
226 ctcmpc_dumpit(buf, len);
227 else
228 ctcmpc_dumpit(buf, 32);
229}
230
231int ctcmpc_open(struct net_device *);
232void ctcm_ccw_check_rc(struct channel *, int, char *);
233void mpc_group_ready(unsigned long adev);
234int mpc_channel_action(struct channel *ch, int direction, int action);
235void mpc_action_send_discontact(unsigned long thischan);
236void mpc_action_discontact(fsm_instance *fi, int event, void *arg);
237void ctcmpc_bh(unsigned long thischan);
238#endif
239/* --- This is the END my friend --- */
diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c
new file mode 100644
index 000000000000..bb2d13721d34
--- /dev/null
+++ b/drivers/s390/net/ctcm_sysfs.c
@@ -0,0 +1,210 @@
1/*
2 * drivers/s390/net/ctcm_sysfs.c
3 *
4 * Copyright IBM Corp. 2007, 2007
5 * Authors: Peter Tiedemann (ptiedem@de.ibm.com)
6 *
7 */
8
9#undef DEBUG
10#undef DEBUGDATA
11#undef DEBUGCCW
12
13#include <linux/sysfs.h>
14#include "ctcm_main.h"
15
16/*
17 * sysfs attributes
18 */
19
20static ssize_t ctcm_buffer_show(struct device *dev,
21 struct device_attribute *attr, char *buf)
22{
23 struct ctcm_priv *priv = dev_get_drvdata(dev);
24
25 if (!priv)
26 return -ENODEV;
27 return sprintf(buf, "%d\n", priv->buffer_size);
28}
29
30static ssize_t ctcm_buffer_write(struct device *dev,
31 struct device_attribute *attr, const char *buf, size_t count)
32{
33 struct net_device *ndev;
34 int bs1;
35 struct ctcm_priv *priv = dev_get_drvdata(dev);
36
37 if (!(priv && priv->channel[READ] &&
38 (ndev = priv->channel[READ]->netdev))) {
39 CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, "bfnondev");
40 return -ENODEV;
41 }
42
43 sscanf(buf, "%u", &bs1);
44 if (bs1 > CTCM_BUFSIZE_LIMIT)
45 goto einval;
46 if (bs1 < (576 + LL_HEADER_LENGTH + 2))
47 goto einval;
48 priv->buffer_size = bs1; /* just to overwrite the default */
49
50 if ((ndev->flags & IFF_RUNNING) &&
51 (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))
52 goto einval;
53
54 priv->channel[READ]->max_bufsize = bs1;
55 priv->channel[WRITE]->max_bufsize = bs1;
56 if (!(ndev->flags & IFF_RUNNING))
57 ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;
58 priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
59 priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
60
61 CTCM_DBF_DEV(SETUP, ndev, buf);
62 return count;
63
64einval:
65 CTCM_DBF_DEV(SETUP, ndev, "buff_err");
66 return -EINVAL;
67}
68
69static void ctcm_print_statistics(struct ctcm_priv *priv)
70{
71 char *sbuf;
72 char *p;
73
74 if (!priv)
75 return;
76 sbuf = kmalloc(2048, GFP_KERNEL);
77 if (sbuf == NULL)
78 return;
79 p = sbuf;
80
81 p += sprintf(p, " Device FSM state: %s\n",
82 fsm_getstate_str(priv->fsm));
83 p += sprintf(p, " RX channel FSM state: %s\n",
84 fsm_getstate_str(priv->channel[READ]->fsm));
85 p += sprintf(p, " TX channel FSM state: %s\n",
86 fsm_getstate_str(priv->channel[WRITE]->fsm));
87 p += sprintf(p, " Max. TX buffer used: %ld\n",
88 priv->channel[WRITE]->prof.maxmulti);
89 p += sprintf(p, " Max. chained SKBs: %ld\n",
90 priv->channel[WRITE]->prof.maxcqueue);
91 p += sprintf(p, " TX single write ops: %ld\n",
92 priv->channel[WRITE]->prof.doios_single);
93 p += sprintf(p, " TX multi write ops: %ld\n",
94 priv->channel[WRITE]->prof.doios_multi);
95 p += sprintf(p, " Netto bytes written: %ld\n",
96 priv->channel[WRITE]->prof.txlen);
97 p += sprintf(p, " Max. TX IO-time: %ld\n",
98 priv->channel[WRITE]->prof.tx_time);
99
100 printk(KERN_INFO "Statistics for %s:\n%s",
101 priv->channel[WRITE]->netdev->name, sbuf);
102 kfree(sbuf);
103 return;
104}
105
106static ssize_t stats_show(struct device *dev,
107 struct device_attribute *attr, char *buf)
108{
109 struct ctcm_priv *priv = dev_get_drvdata(dev);
110 if (!priv)
111 return -ENODEV;
112 ctcm_print_statistics(priv);
113 return sprintf(buf, "0\n");
114}
115
116static ssize_t stats_write(struct device *dev, struct device_attribute *attr,
117 const char *buf, size_t count)
118{
119 struct ctcm_priv *priv = dev_get_drvdata(dev);
120 if (!priv)
121 return -ENODEV;
122 /* Reset statistics */
123 memset(&priv->channel[WRITE]->prof, 0,
124 sizeof(priv->channel[WRITE]->prof));
125 return count;
126}
127
128static ssize_t ctcm_proto_show(struct device *dev,
129 struct device_attribute *attr, char *buf)
130{
131 struct ctcm_priv *priv = dev_get_drvdata(dev);
132 if (!priv)
133 return -ENODEV;
134
135 return sprintf(buf, "%d\n", priv->protocol);
136}
137
138static ssize_t ctcm_proto_store(struct device *dev,
139 struct device_attribute *attr, const char *buf, size_t count)
140{
141 int value;
142 struct ctcm_priv *priv = dev_get_drvdata(dev);
143
144 if (!priv)
145 return -ENODEV;
146 sscanf(buf, "%u", &value);
147 if (!((value == CTCM_PROTO_S390) ||
148 (value == CTCM_PROTO_LINUX) ||
149 (value == CTCM_PROTO_MPC) ||
150 (value == CTCM_PROTO_OS390)))
151 return -EINVAL;
152 priv->protocol = value;
153 CTCM_DBF_DEV(SETUP, dev, buf);
154
155 return count;
156}
157
158static ssize_t ctcm_type_show(struct device *dev,
159 struct device_attribute *attr, char *buf)
160{
161 struct ccwgroup_device *cgdev;
162
163 cgdev = to_ccwgroupdev(dev);
164 if (!cgdev)
165 return -ENODEV;
166
167 return sprintf(buf, "%s\n",
168 cu3088_type[cgdev->cdev[0]->id.driver_info]);
169}
170
171static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write);
172static DEVICE_ATTR(protocol, 0644, ctcm_proto_show, ctcm_proto_store);
173static DEVICE_ATTR(type, 0444, ctcm_type_show, NULL);
174static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
175
176static struct attribute *ctcm_attr[] = {
177 &dev_attr_protocol.attr,
178 &dev_attr_type.attr,
179 &dev_attr_buffer.attr,
180 NULL,
181};
182
183static struct attribute_group ctcm_attr_group = {
184 .attrs = ctcm_attr,
185};
186
187int ctcm_add_attributes(struct device *dev)
188{
189 int rc;
190
191 rc = device_create_file(dev, &dev_attr_stats);
192
193 return rc;
194}
195
196void ctcm_remove_attributes(struct device *dev)
197{
198 device_remove_file(dev, &dev_attr_stats);
199}
200
201int ctcm_add_files(struct device *dev)
202{
203 return sysfs_create_group(&dev->kobj, &ctcm_attr_group);
204}
205
206void ctcm_remove_files(struct device *dev)
207{
208 sysfs_remove_group(&dev->kobj, &ctcm_attr_group);
209}
210
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
deleted file mode 100644
index 77a503139e32..000000000000
--- a/drivers/s390/net/ctcmain.c
+++ /dev/null
@@ -1,3062 +0,0 @@
1/*
2 * CTC / ESCON network driver
3 *
4 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
6 * Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
7 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
8 Peter Tiedemann (ptiedem@de.ibm.com)
9 * Driver Model stuff by : Cornelia Huck <cornelia.huck@de.ibm.com>
10 *
11 * Documentation used:
12 * - Principles of Operation (IBM doc#: SA22-7201-06)
13 * - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02)
14 * - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535)
15 * - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00)
16 * - ESCON I/O Interface (IBM doc#: SA22-7202-029
17 *
18 * and the source of the original CTC driver by:
19 * Dieter Wellerdiek (wel@de.ibm.com)
20 * Martin Schwidefsky (schwidefsky@de.ibm.com)
21 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
22 * Jochen Röhrig (roehrig@de.ibm.com)
23 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2, or (at your option)
27 * any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 *
38 */
39#undef DEBUG
40#include <linux/module.h>
41#include <linux/init.h>
42#include <linux/kernel.h>
43#include <linux/slab.h>
44#include <linux/errno.h>
45#include <linux/types.h>
46#include <linux/interrupt.h>
47#include <linux/timer.h>
48#include <linux/bitops.h>
49
50#include <linux/signal.h>
51#include <linux/string.h>
52
53#include <linux/ip.h>
54#include <linux/if_arp.h>
55#include <linux/tcp.h>
56#include <linux/skbuff.h>
57#include <linux/ctype.h>
58#include <net/dst.h>
59
60#include <asm/io.h>
61#include <asm/ccwdev.h>
62#include <asm/ccwgroup.h>
63#include <asm/uaccess.h>
64
65#include <asm/idals.h>
66
67#include "fsm.h"
68#include "cu3088.h"
69
70#include "ctcdbug.h"
71#include "ctcmain.h"
72
73MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
74MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
75MODULE_LICENSE("GPL");
76/**
77 * States of the interface statemachine.
78 */
79enum dev_states {
80 DEV_STATE_STOPPED,
81 DEV_STATE_STARTWAIT_RXTX,
82 DEV_STATE_STARTWAIT_RX,
83 DEV_STATE_STARTWAIT_TX,
84 DEV_STATE_STOPWAIT_RXTX,
85 DEV_STATE_STOPWAIT_RX,
86 DEV_STATE_STOPWAIT_TX,
87 DEV_STATE_RUNNING,
88 /**
89 * MUST be always the last element!!
90 */
91 CTC_NR_DEV_STATES
92};
93
94static const char *dev_state_names[] = {
95 "Stopped",
96 "StartWait RXTX",
97 "StartWait RX",
98 "StartWait TX",
99 "StopWait RXTX",
100 "StopWait RX",
101 "StopWait TX",
102 "Running",
103};
104
105/**
106 * Events of the interface statemachine.
107 */
108enum dev_events {
109 DEV_EVENT_START,
110 DEV_EVENT_STOP,
111 DEV_EVENT_RXUP,
112 DEV_EVENT_TXUP,
113 DEV_EVENT_RXDOWN,
114 DEV_EVENT_TXDOWN,
115 DEV_EVENT_RESTART,
116 /**
117 * MUST be always the last element!!
118 */
119 CTC_NR_DEV_EVENTS
120};
121
122static const char *dev_event_names[] = {
123 "Start",
124 "Stop",
125 "RX up",
126 "TX up",
127 "RX down",
128 "TX down",
129 "Restart",
130};
131
132/**
133 * Events of the channel statemachine
134 */
135enum ch_events {
136 /**
137 * Events, representing return code of
138 * I/O operations (ccw_device_start, ccw_device_halt et al.)
139 */
140 CH_EVENT_IO_SUCCESS,
141 CH_EVENT_IO_EBUSY,
142 CH_EVENT_IO_ENODEV,
143 CH_EVENT_IO_EIO,
144 CH_EVENT_IO_UNKNOWN,
145
146 CH_EVENT_ATTNBUSY,
147 CH_EVENT_ATTN,
148 CH_EVENT_BUSY,
149
150 /**
151 * Events, representing unit-check
152 */
153 CH_EVENT_UC_RCRESET,
154 CH_EVENT_UC_RSRESET,
155 CH_EVENT_UC_TXTIMEOUT,
156 CH_EVENT_UC_TXPARITY,
157 CH_EVENT_UC_HWFAIL,
158 CH_EVENT_UC_RXPARITY,
159 CH_EVENT_UC_ZERO,
160 CH_EVENT_UC_UNKNOWN,
161
162 /**
163 * Events, representing subchannel-check
164 */
165 CH_EVENT_SC_UNKNOWN,
166
167 /**
168 * Events, representing machine checks
169 */
170 CH_EVENT_MC_FAIL,
171 CH_EVENT_MC_GOOD,
172
173 /**
174 * Event, representing normal IRQ
175 */
176 CH_EVENT_IRQ,
177 CH_EVENT_FINSTAT,
178
179 /**
180 * Event, representing timer expiry.
181 */
182 CH_EVENT_TIMER,
183
184 /**
185 * Events, representing commands from upper levels.
186 */
187 CH_EVENT_START,
188 CH_EVENT_STOP,
189
190 /**
191 * MUST be always the last element!!
192 */
193 NR_CH_EVENTS,
194};
195
196/**
197 * States of the channel statemachine.
198 */
199enum ch_states {
200 /**
201 * Channel not assigned to any device,
202 * initial state, direction invalid
203 */
204 CH_STATE_IDLE,
205
206 /**
207 * Channel assigned but not operating
208 */
209 CH_STATE_STOPPED,
210 CH_STATE_STARTWAIT,
211 CH_STATE_STARTRETRY,
212 CH_STATE_SETUPWAIT,
213 CH_STATE_RXINIT,
214 CH_STATE_TXINIT,
215 CH_STATE_RX,
216 CH_STATE_TX,
217 CH_STATE_RXIDLE,
218 CH_STATE_TXIDLE,
219 CH_STATE_RXERR,
220 CH_STATE_TXERR,
221 CH_STATE_TERM,
222 CH_STATE_DTERM,
223 CH_STATE_NOTOP,
224
225 /**
226 * MUST be always the last element!!
227 */
228 NR_CH_STATES,
229};
230
231static int loglevel = CTC_LOGLEVEL_DEFAULT;
232
233/**
234 * Linked list of all detected channels.
235 */
236static struct channel *channels = NULL;
237
238/**
239 * Print Banner.
240 */
241static void
242print_banner(void)
243{
244 static int printed = 0;
245
246 if (printed)
247 return;
248
249 printk(KERN_INFO "CTC driver initialized\n");
250 printed = 1;
251}
252
253/**
254 * Return type of a detected device.
255 */
256static enum channel_types
257get_channel_type(struct ccw_device_id *id)
258{
259 enum channel_types type = (enum channel_types) id->driver_info;
260
261 if (type == channel_type_ficon)
262 type = channel_type_escon;
263
264 return type;
265}
266
267static const char *ch_event_names[] = {
268 "ccw_device success",
269 "ccw_device busy",
270 "ccw_device enodev",
271 "ccw_device ioerr",
272 "ccw_device unknown",
273
274 "Status ATTN & BUSY",
275 "Status ATTN",
276 "Status BUSY",
277
278 "Unit check remote reset",
279 "Unit check remote system reset",
280 "Unit check TX timeout",
281 "Unit check TX parity",
282 "Unit check Hardware failure",
283 "Unit check RX parity",
284 "Unit check ZERO",
285 "Unit check Unknown",
286
287 "SubChannel check Unknown",
288
289 "Machine check failure",
290 "Machine check operational",
291
292 "IRQ normal",
293 "IRQ final",
294
295 "Timer",
296
297 "Start",
298 "Stop",
299};
300
301static const char *ch_state_names[] = {
302 "Idle",
303 "Stopped",
304 "StartWait",
305 "StartRetry",
306 "SetupWait",
307 "RX init",
308 "TX init",
309 "RX",
310 "TX",
311 "RX idle",
312 "TX idle",
313 "RX error",
314 "TX error",
315 "Terminating",
316 "Restarting",
317 "Not operational",
318};
319
320#ifdef DEBUG
321/**
322 * Dump header and first 16 bytes of an sk_buff for debugging purposes.
323 *
324 * @param skb The sk_buff to dump.
325 * @param offset Offset relative to skb-data, where to start the dump.
326 */
327static void
328ctc_dump_skb(struct sk_buff *skb, int offset)
329{
330 unsigned char *p = skb->data;
331 __u16 bl;
332 struct ll_header *header;
333 int i;
334
335 if (!(loglevel & CTC_LOGLEVEL_DEBUG))
336 return;
337 p += offset;
338 bl = *((__u16 *) p);
339 p += 2;
340 header = (struct ll_header *) p;
341 p -= 2;
342
343 printk(KERN_DEBUG "dump:\n");
344 printk(KERN_DEBUG "blocklen=%d %04x\n", bl, bl);
345
346 printk(KERN_DEBUG "h->length=%d %04x\n", header->length,
347 header->length);
348 printk(KERN_DEBUG "h->type=%04x\n", header->type);
349 printk(KERN_DEBUG "h->unused=%04x\n", header->unused);
350 if (bl > 16)
351 bl = 16;
352 printk(KERN_DEBUG "data: ");
353 for (i = 0; i < bl; i++)
354 printk("%02x%s", *p++, (i % 16) ? " " : "\n<7>");
355 printk("\n");
356}
357#else
358static inline void
359ctc_dump_skb(struct sk_buff *skb, int offset)
360{
361}
362#endif
363
364/**
365 * Unpack a just received skb and hand it over to
366 * upper layers.
367 *
368 * @param ch The channel where this skb has been received.
369 * @param pskb The received skb.
370 */
371static void
372ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
373{
374 struct net_device *dev = ch->netdev;
375 struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
376 __u16 len = *((__u16 *) pskb->data);
377
378 DBF_TEXT(trace, 4, __FUNCTION__);
379 skb_put(pskb, 2 + LL_HEADER_LENGTH);
380 skb_pull(pskb, 2);
381 pskb->dev = dev;
382 pskb->ip_summed = CHECKSUM_UNNECESSARY;
383 while (len > 0) {
384 struct sk_buff *skb;
385 struct ll_header *header = (struct ll_header *) pskb->data;
386
387 skb_pull(pskb, LL_HEADER_LENGTH);
388 if ((ch->protocol == CTC_PROTO_S390) &&
389 (header->type != ETH_P_IP)) {
390
391#ifndef DEBUG
392 if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) {
393#endif
394 /**
395 * Check packet type only if we stick strictly
396 * to S/390's protocol of OS390. This only
397 * supports IP. Otherwise allow any packet
398 * type.
399 */
400 ctc_pr_warn(
401 "%s Illegal packet type 0x%04x received, dropping\n",
402 dev->name, header->type);
403 ch->logflags |= LOG_FLAG_ILLEGALPKT;
404#ifndef DEBUG
405 }
406#endif
407#ifdef DEBUG
408 ctc_dump_skb(pskb, -6);
409#endif
410 privptr->stats.rx_dropped++;
411 privptr->stats.rx_frame_errors++;
412 return;
413 }
414 pskb->protocol = ntohs(header->type);
415 if (header->length <= LL_HEADER_LENGTH) {
416#ifndef DEBUG
417 if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
418#endif
419 ctc_pr_warn(
420 "%s Illegal packet size %d "
421 "received (MTU=%d blocklen=%d), "
422 "dropping\n", dev->name, header->length,
423 dev->mtu, len);
424 ch->logflags |= LOG_FLAG_ILLEGALSIZE;
425#ifndef DEBUG
426 }
427#endif
428#ifdef DEBUG
429 ctc_dump_skb(pskb, -6);
430#endif
431 privptr->stats.rx_dropped++;
432 privptr->stats.rx_length_errors++;
433 return;
434 }
435 header->length -= LL_HEADER_LENGTH;
436 len -= LL_HEADER_LENGTH;
437 if ((header->length > skb_tailroom(pskb)) ||
438 (header->length > len)) {
439#ifndef DEBUG
440 if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
441#endif
442 ctc_pr_warn(
443 "%s Illegal packet size %d "
444 "(beyond the end of received data), "
445 "dropping\n", dev->name, header->length);
446 ch->logflags |= LOG_FLAG_OVERRUN;
447#ifndef DEBUG
448 }
449#endif
450#ifdef DEBUG
451 ctc_dump_skb(pskb, -6);
452#endif
453 privptr->stats.rx_dropped++;
454 privptr->stats.rx_length_errors++;
455 return;
456 }
457 skb_put(pskb, header->length);
458 skb_reset_mac_header(pskb);
459 len -= header->length;
460 skb = dev_alloc_skb(pskb->len);
461 if (!skb) {
462#ifndef DEBUG
463 if (!(ch->logflags & LOG_FLAG_NOMEM)) {
464#endif
465 ctc_pr_warn(
466 "%s Out of memory in ctc_unpack_skb\n",
467 dev->name);
468 ch->logflags |= LOG_FLAG_NOMEM;
469#ifndef DEBUG
470 }
471#endif
472 privptr->stats.rx_dropped++;
473 return;
474 }
475 skb_copy_from_linear_data(pskb, skb_put(skb, pskb->len),
476 pskb->len);
477 skb_reset_mac_header(skb);
478 skb->dev = pskb->dev;
479 skb->protocol = pskb->protocol;
480 pskb->ip_summed = CHECKSUM_UNNECESSARY;
481 /**
482 * reset logflags
483 */
484 ch->logflags = 0;
485 privptr->stats.rx_packets++;
486 privptr->stats.rx_bytes += skb->len;
487 netif_rx_ni(skb);
488 dev->last_rx = jiffies;
489 if (len > 0) {
490 skb_pull(pskb, header->length);
491 if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
492#ifndef DEBUG
493 if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
494#endif
495 ctc_pr_warn(
496 "%s Overrun in ctc_unpack_skb\n",
497 dev->name);
498 ch->logflags |= LOG_FLAG_OVERRUN;
499#ifndef DEBUG
500 }
501#endif
502 return;
503 }
504 skb_put(pskb, LL_HEADER_LENGTH);
505 }
506 }
507}
508
509/**
510 * Check return code of a preceeding ccw_device call, halt_IO etc...
511 *
512 * @param ch The channel, the error belongs to.
513 * @param return_code The error code to inspect.
514 */
515static void
516ccw_check_return_code(struct channel *ch, int return_code, char *msg)
517{
518 DBF_TEXT(trace, 5, __FUNCTION__);
519 switch (return_code) {
520 case 0:
521 fsm_event(ch->fsm, CH_EVENT_IO_SUCCESS, ch);
522 break;
523 case -EBUSY:
524 ctc_pr_warn("%s (%s): Busy !\n", ch->id, msg);
525 fsm_event(ch->fsm, CH_EVENT_IO_EBUSY, ch);
526 break;
527 case -ENODEV:
528 ctc_pr_emerg("%s (%s): Invalid device called for IO\n",
529 ch->id, msg);
530 fsm_event(ch->fsm, CH_EVENT_IO_ENODEV, ch);
531 break;
532 case -EIO:
533 ctc_pr_emerg("%s (%s): Status pending... \n",
534 ch->id, msg);
535 fsm_event(ch->fsm, CH_EVENT_IO_EIO, ch);
536 break;
537 default:
538 ctc_pr_emerg("%s (%s): Unknown error in do_IO %04x\n",
539 ch->id, msg, return_code);
540 fsm_event(ch->fsm, CH_EVENT_IO_UNKNOWN, ch);
541 }
542}
543
544/**
545 * Check sense of a unit check.
546 *
547 * @param ch The channel, the sense code belongs to.
548 * @param sense The sense code to inspect.
549 */
550static void
551ccw_unit_check(struct channel *ch, unsigned char sense)
552{
553 DBF_TEXT(trace, 5, __FUNCTION__);
554 if (sense & SNS0_INTERVENTION_REQ) {
555 if (sense & 0x01) {
556 ctc_pr_debug("%s: Interface disc. or Sel. reset "
557 "(remote)\n", ch->id);
558 fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);
559 } else {
560 ctc_pr_debug("%s: System reset (remote)\n", ch->id);
561 fsm_event(ch->fsm, CH_EVENT_UC_RSRESET, ch);
562 }
563 } else if (sense & SNS0_EQUIPMENT_CHECK) {
564 if (sense & SNS0_BUS_OUT_CHECK) {
565 ctc_pr_warn("%s: Hardware malfunction (remote)\n",
566 ch->id);
567 fsm_event(ch->fsm, CH_EVENT_UC_HWFAIL, ch);
568 } else {
569 ctc_pr_warn("%s: Read-data parity error (remote)\n",
570 ch->id);
571 fsm_event(ch->fsm, CH_EVENT_UC_RXPARITY, ch);
572 }
573 } else if (sense & SNS0_BUS_OUT_CHECK) {
574 if (sense & 0x04) {
575 ctc_pr_warn("%s: Data-streaming timeout)\n", ch->id);
576 fsm_event(ch->fsm, CH_EVENT_UC_TXTIMEOUT, ch);
577 } else {
578 ctc_pr_warn("%s: Data-transfer parity error\n", ch->id);
579 fsm_event(ch->fsm, CH_EVENT_UC_TXPARITY, ch);
580 }
581 } else if (sense & SNS0_CMD_REJECT) {
582 ctc_pr_warn("%s: Command reject\n", ch->id);
583 } else if (sense == 0) {
584 ctc_pr_debug("%s: Unit check ZERO\n", ch->id);
585 fsm_event(ch->fsm, CH_EVENT_UC_ZERO, ch);
586 } else {
587 ctc_pr_warn("%s: Unit Check with sense code: %02x\n",
588 ch->id, sense);
589 fsm_event(ch->fsm, CH_EVENT_UC_UNKNOWN, ch);
590 }
591}
592
593static void
594ctc_purge_skb_queue(struct sk_buff_head *q)
595{
596 struct sk_buff *skb;
597
598 DBF_TEXT(trace, 5, __FUNCTION__);
599
600 while ((skb = skb_dequeue(q))) {
601 atomic_dec(&skb->users);
602 dev_kfree_skb_irq(skb);
603 }
604}
605
606static int
607ctc_checkalloc_buffer(struct channel *ch, int warn)
608{
609 DBF_TEXT(trace, 5, __FUNCTION__);
610 if ((ch->trans_skb == NULL) ||
611 (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED)) {
612 if (ch->trans_skb != NULL)
613 dev_kfree_skb(ch->trans_skb);
614 clear_normalized_cda(&ch->ccw[1]);
615 ch->trans_skb = __dev_alloc_skb(ch->max_bufsize,
616 GFP_ATOMIC | GFP_DMA);
617 if (ch->trans_skb == NULL) {
618 if (warn)
619 ctc_pr_warn(
620 "%s: Couldn't alloc %s trans_skb\n",
621 ch->id,
622 (CHANNEL_DIRECTION(ch->flags) == READ) ?
623 "RX" : "TX");
624 return -ENOMEM;
625 }
626 ch->ccw[1].count = ch->max_bufsize;
627 if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
628 dev_kfree_skb(ch->trans_skb);
629 ch->trans_skb = NULL;
630 if (warn)
631 ctc_pr_warn(
632 "%s: set_normalized_cda for %s "
633 "trans_skb failed, dropping packets\n",
634 ch->id,
635 (CHANNEL_DIRECTION(ch->flags) == READ) ?
636 "RX" : "TX");
637 return -ENOMEM;
638 }
639 ch->ccw[1].count = 0;
640 ch->trans_skb_data = ch->trans_skb->data;
641 ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED;
642 }
643 return 0;
644}
645
646/**
647 * Dummy NOP action for statemachines
648 */
649static void
650fsm_action_nop(fsm_instance * fi, int event, void *arg)
651{
652}
653
654/**
655 * Actions for channel - statemachines.
656 *****************************************************************************/
657
658/**
659 * Normal data has been send. Free the corresponding
660 * skb (it's in io_queue), reset dev->tbusy and
661 * revert to idle state.
662 *
663 * @param fi An instance of a channel statemachine.
664 * @param event The event, just happened.
665 * @param arg Generic pointer, casted from channel * upon call.
666 */
667static void
668ch_action_txdone(fsm_instance * fi, int event, void *arg)
669{
670 struct channel *ch = (struct channel *) arg;
671 struct net_device *dev = ch->netdev;
672 struct ctc_priv *privptr = dev->priv;
673 struct sk_buff *skb;
674 int first = 1;
675 int i;
676 unsigned long duration;
677 struct timespec done_stamp = current_kernel_time();
678
679 DBF_TEXT(trace, 4, __FUNCTION__);
680
681 duration =
682 (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
683 (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
684 if (duration > ch->prof.tx_time)
685 ch->prof.tx_time = duration;
686
687 if (ch->irb->scsw.count != 0)
688 ctc_pr_debug("%s: TX not complete, remaining %d bytes\n",
689 dev->name, ch->irb->scsw.count);
690 fsm_deltimer(&ch->timer);
691 while ((skb = skb_dequeue(&ch->io_queue))) {
692 privptr->stats.tx_packets++;
693 privptr->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
694 if (first) {
695 privptr->stats.tx_bytes += 2;
696 first = 0;
697 }
698 atomic_dec(&skb->users);
699 dev_kfree_skb_irq(skb);
700 }
701 spin_lock(&ch->collect_lock);
702 clear_normalized_cda(&ch->ccw[4]);
703 if (ch->collect_len > 0) {
704 int rc;
705
706 if (ctc_checkalloc_buffer(ch, 1)) {
707 spin_unlock(&ch->collect_lock);
708 return;
709 }
710 ch->trans_skb->data = ch->trans_skb_data;
711 skb_reset_tail_pointer(ch->trans_skb);
712 ch->trans_skb->len = 0;
713 if (ch->prof.maxmulti < (ch->collect_len + 2))
714 ch->prof.maxmulti = ch->collect_len + 2;
715 if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))
716 ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);
717 *((__u16 *) skb_put(ch->trans_skb, 2)) = ch->collect_len + 2;
718 i = 0;
719 while ((skb = skb_dequeue(&ch->collect_queue))) {
720 skb_copy_from_linear_data(skb, skb_put(ch->trans_skb,
721 skb->len),
722 skb->len);
723 privptr->stats.tx_packets++;
724 privptr->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
725 atomic_dec(&skb->users);
726 dev_kfree_skb_irq(skb);
727 i++;
728 }
729 ch->collect_len = 0;
730 spin_unlock(&ch->collect_lock);
731 ch->ccw[1].count = ch->trans_skb->len;
732 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
733 ch->prof.send_stamp = current_kernel_time();
734 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
735 (unsigned long) ch, 0xff, 0);
736 ch->prof.doios_multi++;
737 if (rc != 0) {
738 privptr->stats.tx_dropped += i;
739 privptr->stats.tx_errors += i;
740 fsm_deltimer(&ch->timer);
741 ccw_check_return_code(ch, rc, "chained TX");
742 }
743 } else {
744 spin_unlock(&ch->collect_lock);
745 fsm_newstate(fi, CH_STATE_TXIDLE);
746 }
747 ctc_clear_busy(dev);
748}
749
750/**
751 * Initial data is sent.
752 * Notify device statemachine that we are up and
753 * running.
754 *
755 * @param fi An instance of a channel statemachine.
756 * @param event The event, just happened.
757 * @param arg Generic pointer, casted from channel * upon call.
758 */
759static void
760ch_action_txidle(fsm_instance * fi, int event, void *arg)
761{
762 struct channel *ch = (struct channel *) arg;
763
764 DBF_TEXT(trace, 4, __FUNCTION__);
765 fsm_deltimer(&ch->timer);
766 fsm_newstate(fi, CH_STATE_TXIDLE);
767 fsm_event(((struct ctc_priv *) ch->netdev->priv)->fsm, DEV_EVENT_TXUP,
768 ch->netdev);
769}
770
771/**
772 * Got normal data, check for sanity, queue it up, allocate new buffer
773 * trigger bottom half, and initiate next read.
774 *
775 * @param fi An instance of a channel statemachine.
776 * @param event The event, just happened.
777 * @param arg Generic pointer, casted from channel * upon call.
778 */
779static void
780ch_action_rx(fsm_instance * fi, int event, void *arg)
781{
782 struct channel *ch = (struct channel *) arg;
783 struct net_device *dev = ch->netdev;
784 struct ctc_priv *privptr = dev->priv;
785 int len = ch->max_bufsize - ch->irb->scsw.count;
786 struct sk_buff *skb = ch->trans_skb;
787 __u16 block_len = *((__u16 *) skb->data);
788 int check_len;
789 int rc;
790
791 DBF_TEXT(trace, 4, __FUNCTION__);
792 fsm_deltimer(&ch->timer);
793 if (len < 8) {
794 ctc_pr_debug("%s: got packet with length %d < 8\n",
795 dev->name, len);
796 privptr->stats.rx_dropped++;
797 privptr->stats.rx_length_errors++;
798 goto again;
799 }
800 if (len > ch->max_bufsize) {
801 ctc_pr_debug("%s: got packet with length %d > %d\n",
802 dev->name, len, ch->max_bufsize);
803 privptr->stats.rx_dropped++;
804 privptr->stats.rx_length_errors++;
805 goto again;
806 }
807
808 /**
809 * VM TCP seems to have a bug sending 2 trailing bytes of garbage.
810 */
811 switch (ch->protocol) {
812 case CTC_PROTO_S390:
813 case CTC_PROTO_OS390:
814 check_len = block_len + 2;
815 break;
816 default:
817 check_len = block_len;
818 break;
819 }
820 if ((len < block_len) || (len > check_len)) {
821 ctc_pr_debug("%s: got block length %d != rx length %d\n",
822 dev->name, block_len, len);
823#ifdef DEBUG
824 ctc_dump_skb(skb, 0);
825#endif
826 *((__u16 *) skb->data) = len;
827 privptr->stats.rx_dropped++;
828 privptr->stats.rx_length_errors++;
829 goto again;
830 }
831 block_len -= 2;
832 if (block_len > 0) {
833 *((__u16 *) skb->data) = block_len;
834 ctc_unpack_skb(ch, skb);
835 }
836 again:
837 skb->data = ch->trans_skb_data;
838 skb_reset_tail_pointer(skb);
839 skb->len = 0;
840 if (ctc_checkalloc_buffer(ch, 1))
841 return;
842 ch->ccw[1].count = ch->max_bufsize;
843 rc = ccw_device_start(ch->cdev, &ch->ccw[0], (unsigned long) ch, 0xff, 0);
844 if (rc != 0)
845 ccw_check_return_code(ch, rc, "normal RX");
846}
847
848static void ch_action_rxidle(fsm_instance * fi, int event, void *arg);
849
850/**
851 * Initialize connection by sending a __u16 of value 0.
852 *
853 * @param fi An instance of a channel statemachine.
854 * @param event The event, just happened.
855 * @param arg Generic pointer, casted from channel * upon call.
856 */
857static void
858ch_action_firstio(fsm_instance * fi, int event, void *arg)
859{
860 struct channel *ch = (struct channel *) arg;
861 int rc;
862
863 DBF_TEXT(trace, 4, __FUNCTION__);
864
865 if (fsm_getstate(fi) == CH_STATE_TXIDLE)
866 ctc_pr_debug("%s: remote side issued READ?, init ...\n", ch->id);
867 fsm_deltimer(&ch->timer);
868 if (ctc_checkalloc_buffer(ch, 1))
869 return;
870 if ((fsm_getstate(fi) == CH_STATE_SETUPWAIT) &&
871 (ch->protocol == CTC_PROTO_OS390)) {
872 /* OS/390 resp. z/OS */
873 if (CHANNEL_DIRECTION(ch->flags) == READ) {
874 *((__u16 *) ch->trans_skb->data) = CTC_INITIAL_BLOCKLEN;
875 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC,
876 CH_EVENT_TIMER, ch);
877 ch_action_rxidle(fi, event, arg);
878 } else {
879 struct net_device *dev = ch->netdev;
880 fsm_newstate(fi, CH_STATE_TXIDLE);
881 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
882 DEV_EVENT_TXUP, dev);
883 }
884 return;
885 }
886
887 /**
888 * Don't setup a timer for receiving the initial RX frame
889 * if in compatibility mode, since VM TCP delays the initial
890 * frame until it has some data to send.
891 */
892 if ((CHANNEL_DIRECTION(ch->flags) == WRITE) ||
893 (ch->protocol != CTC_PROTO_S390))
894 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
895
896 *((__u16 *) ch->trans_skb->data) = CTC_INITIAL_BLOCKLEN;
897 ch->ccw[1].count = 2; /* Transfer only length */
898
899 fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == READ)
900 ? CH_STATE_RXINIT : CH_STATE_TXINIT);
901 rc = ccw_device_start(ch->cdev, &ch->ccw[0], (unsigned long) ch, 0xff, 0);
902 if (rc != 0) {
903 fsm_deltimer(&ch->timer);
904 fsm_newstate(fi, CH_STATE_SETUPWAIT);
905 ccw_check_return_code(ch, rc, "init IO");
906 }
907 /**
908 * If in compatibility mode since we don't setup a timer, we
909 * also signal RX channel up immediately. This enables us
910 * to send packets early which in turn usually triggers some
911 * reply from VM TCP which brings up the RX channel to it's
912 * final state.
913 */
914 if ((CHANNEL_DIRECTION(ch->flags) == READ) &&
915 (ch->protocol == CTC_PROTO_S390)) {
916 struct net_device *dev = ch->netdev;
917 fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_RXUP,
918 dev);
919 }
920}
921
922/**
923 * Got initial data, check it. If OK,
924 * notify device statemachine that we are up and
925 * running.
926 *
927 * @param fi An instance of a channel statemachine.
928 * @param event The event, just happened.
929 * @param arg Generic pointer, casted from channel * upon call.
930 */
931static void
932ch_action_rxidle(fsm_instance * fi, int event, void *arg)
933{
934 struct channel *ch = (struct channel *) arg;
935 struct net_device *dev = ch->netdev;
936 __u16 buflen;
937 int rc;
938
939 DBF_TEXT(trace, 4, __FUNCTION__);
940 fsm_deltimer(&ch->timer);
941 buflen = *((__u16 *) ch->trans_skb->data);
942#ifdef DEBUG
943 ctc_pr_debug("%s: Initial RX count %d\n", dev->name, buflen);
944#endif
945 if (buflen >= CTC_INITIAL_BLOCKLEN) {
946 if (ctc_checkalloc_buffer(ch, 1))
947 return;
948 ch->ccw[1].count = ch->max_bufsize;
949 fsm_newstate(fi, CH_STATE_RXIDLE);
950 rc = ccw_device_start(ch->cdev, &ch->ccw[0],
951 (unsigned long) ch, 0xff, 0);
952 if (rc != 0) {
953 fsm_newstate(fi, CH_STATE_RXINIT);
954 ccw_check_return_code(ch, rc, "initial RX");
955 } else
956 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
957 DEV_EVENT_RXUP, dev);
958 } else {
959 ctc_pr_debug("%s: Initial RX count %d not %d\n",
960 dev->name, buflen, CTC_INITIAL_BLOCKLEN);
961 ch_action_firstio(fi, event, arg);
962 }
963}
964
965/**
966 * Set channel into extended mode.
967 *
968 * @param fi An instance of a channel statemachine.
969 * @param event The event, just happened.
970 * @param arg Generic pointer, casted from channel * upon call.
971 */
972static void
973ch_action_setmode(fsm_instance * fi, int event, void *arg)
974{
975 struct channel *ch = (struct channel *) arg;
976 int rc;
977 unsigned long saveflags;
978
979 DBF_TEXT(trace, 4, __FUNCTION__);
980 fsm_deltimer(&ch->timer);
981 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
982 fsm_newstate(fi, CH_STATE_SETUPWAIT);
983 saveflags = 0; /* avoids compiler warning with
984 spin_unlock_irqrestore */
985 if (event == CH_EVENT_TIMER) // only for timer not yet locked
986 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
987 rc = ccw_device_start(ch->cdev, &ch->ccw[6], (unsigned long) ch, 0xff, 0);
988 if (event == CH_EVENT_TIMER)
989 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
990 if (rc != 0) {
991 fsm_deltimer(&ch->timer);
992 fsm_newstate(fi, CH_STATE_STARTWAIT);
993 ccw_check_return_code(ch, rc, "set Mode");
994 } else
995 ch->retry = 0;
996}
997
998/**
999 * Setup channel.
1000 *
1001 * @param fi An instance of a channel statemachine.
1002 * @param event The event, just happened.
1003 * @param arg Generic pointer, casted from channel * upon call.
1004 */
1005static void
1006ch_action_start(fsm_instance * fi, int event, void *arg)
1007{
1008 struct channel *ch = (struct channel *) arg;
1009 unsigned long saveflags;
1010 int rc;
1011 struct net_device *dev;
1012
1013 DBF_TEXT(trace, 4, __FUNCTION__);
1014 if (ch == NULL) {
1015 ctc_pr_warn("ch_action_start ch=NULL\n");
1016 return;
1017 }
1018 if (ch->netdev == NULL) {
1019 ctc_pr_warn("ch_action_start dev=NULL, id=%s\n", ch->id);
1020 return;
1021 }
1022 dev = ch->netdev;
1023
1024#ifdef DEBUG
1025 ctc_pr_debug("%s: %s channel start\n", dev->name,
1026 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
1027#endif
1028
1029 if (ch->trans_skb != NULL) {
1030 clear_normalized_cda(&ch->ccw[1]);
1031 dev_kfree_skb(ch->trans_skb);
1032 ch->trans_skb = NULL;
1033 }
1034 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1035 ch->ccw[1].cmd_code = CCW_CMD_READ;
1036 ch->ccw[1].flags = CCW_FLAG_SLI;
1037 ch->ccw[1].count = 0;
1038 } else {
1039 ch->ccw[1].cmd_code = CCW_CMD_WRITE;
1040 ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1041 ch->ccw[1].count = 0;
1042 }
1043 if (ctc_checkalloc_buffer(ch, 0)) {
1044 ctc_pr_notice(
1045 "%s: Could not allocate %s trans_skb, delaying "
1046 "allocation until first transfer\n",
1047 dev->name,
1048 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
1049 }
1050
1051 ch->ccw[0].cmd_code = CCW_CMD_PREPARE;
1052 ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
1053 ch->ccw[0].count = 0;
1054 ch->ccw[0].cda = 0;
1055 ch->ccw[2].cmd_code = CCW_CMD_NOOP; /* jointed CE + DE */
1056 ch->ccw[2].flags = CCW_FLAG_SLI;
1057 ch->ccw[2].count = 0;
1058 ch->ccw[2].cda = 0;
1059 memcpy(&ch->ccw[3], &ch->ccw[0], sizeof (struct ccw1) * 3);
1060 ch->ccw[4].cda = 0;
1061 ch->ccw[4].flags &= ~CCW_FLAG_IDA;
1062
1063 fsm_newstate(fi, CH_STATE_STARTWAIT);
1064 fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch);
1065 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
1066 rc = ccw_device_halt(ch->cdev, (unsigned long) ch);
1067 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
1068 if (rc != 0) {
1069 if (rc != -EBUSY)
1070 fsm_deltimer(&ch->timer);
1071 ccw_check_return_code(ch, rc, "initial HaltIO");
1072 }
1073#ifdef DEBUG
1074 ctc_pr_debug("ctc: %s(): leaving\n", __func__);
1075#endif
1076}
1077
1078/**
1079 * Shutdown a channel.
1080 *
1081 * @param fi An instance of a channel statemachine.
1082 * @param event The event, just happened.
1083 * @param arg Generic pointer, casted from channel * upon call.
1084 */
1085static void
1086ch_action_haltio(fsm_instance * fi, int event, void *arg)
1087{
1088 struct channel *ch = (struct channel *) arg;
1089 unsigned long saveflags;
1090 int rc;
1091 int oldstate;
1092
1093 DBF_TEXT(trace, 3, __FUNCTION__);
1094 fsm_deltimer(&ch->timer);
1095 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
1096 saveflags = 0; /* avoids comp warning with
1097 spin_unlock_irqrestore */
1098 if (event == CH_EVENT_STOP) // only for STOP not yet locked
1099 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
1100 oldstate = fsm_getstate(fi);
1101 fsm_newstate(fi, CH_STATE_TERM);
1102 rc = ccw_device_halt(ch->cdev, (unsigned long) ch);
1103 if (event == CH_EVENT_STOP)
1104 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
1105 if (rc != 0) {
1106 if (rc != -EBUSY) {
1107 fsm_deltimer(&ch->timer);
1108 fsm_newstate(fi, oldstate);
1109 }
1110 ccw_check_return_code(ch, rc, "HaltIO in ch_action_haltio");
1111 }
1112}
1113
1114/**
1115 * A channel has successfully been halted.
1116 * Cleanup it's queue and notify interface statemachine.
1117 *
1118 * @param fi An instance of a channel statemachine.
1119 * @param event The event, just happened.
1120 * @param arg Generic pointer, casted from channel * upon call.
1121 */
1122static void
1123ch_action_stopped(fsm_instance * fi, int event, void *arg)
1124{
1125 struct channel *ch = (struct channel *) arg;
1126 struct net_device *dev = ch->netdev;
1127
1128 DBF_TEXT(trace, 3, __FUNCTION__);
1129 fsm_deltimer(&ch->timer);
1130 fsm_newstate(fi, CH_STATE_STOPPED);
1131 if (ch->trans_skb != NULL) {
1132 clear_normalized_cda(&ch->ccw[1]);
1133 dev_kfree_skb(ch->trans_skb);
1134 ch->trans_skb = NULL;
1135 }
1136 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1137 skb_queue_purge(&ch->io_queue);
1138 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1139 DEV_EVENT_RXDOWN, dev);
1140 } else {
1141 ctc_purge_skb_queue(&ch->io_queue);
1142 spin_lock(&ch->collect_lock);
1143 ctc_purge_skb_queue(&ch->collect_queue);
1144 ch->collect_len = 0;
1145 spin_unlock(&ch->collect_lock);
1146 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1147 DEV_EVENT_TXDOWN, dev);
1148 }
1149}
1150
1151/**
1152 * A stop command from device statemachine arrived and we are in
1153 * not operational mode. Set state to stopped.
1154 *
1155 * @param fi An instance of a channel statemachine.
1156 * @param event The event, just happened.
1157 * @param arg Generic pointer, casted from channel * upon call.
1158 */
1159static void
1160ch_action_stop(fsm_instance * fi, int event, void *arg)
1161{
1162 fsm_newstate(fi, CH_STATE_STOPPED);
1163}
1164
1165/**
1166 * A machine check for no path, not operational status or gone device has
1167 * happened.
1168 * Cleanup queue and notify interface statemachine.
1169 *
1170 * @param fi An instance of a channel statemachine.
1171 * @param event The event, just happened.
1172 * @param arg Generic pointer, casted from channel * upon call.
1173 */
1174static void
1175ch_action_fail(fsm_instance * fi, int event, void *arg)
1176{
1177 struct channel *ch = (struct channel *) arg;
1178 struct net_device *dev = ch->netdev;
1179
1180 DBF_TEXT(trace, 3, __FUNCTION__);
1181 fsm_deltimer(&ch->timer);
1182 fsm_newstate(fi, CH_STATE_NOTOP);
1183 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1184 skb_queue_purge(&ch->io_queue);
1185 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1186 DEV_EVENT_RXDOWN, dev);
1187 } else {
1188 ctc_purge_skb_queue(&ch->io_queue);
1189 spin_lock(&ch->collect_lock);
1190 ctc_purge_skb_queue(&ch->collect_queue);
1191 ch->collect_len = 0;
1192 spin_unlock(&ch->collect_lock);
1193 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1194 DEV_EVENT_TXDOWN, dev);
1195 }
1196}
1197
1198/**
1199 * Handle error during setup of channel.
1200 *
1201 * @param fi An instance of a channel statemachine.
1202 * @param event The event, just happened.
1203 * @param arg Generic pointer, casted from channel * upon call.
1204 */
1205static void
1206ch_action_setuperr(fsm_instance * fi, int event, void *arg)
1207{
1208 struct channel *ch = (struct channel *) arg;
1209 struct net_device *dev = ch->netdev;
1210
1211 DBF_TEXT(setup, 3, __FUNCTION__);
1212 /**
1213 * Special case: Got UC_RCRESET on setmode.
1214 * This means that remote side isn't setup. In this case
1215 * simply retry after some 10 secs...
1216 */
1217 if ((fsm_getstate(fi) == CH_STATE_SETUPWAIT) &&
1218 ((event == CH_EVENT_UC_RCRESET) ||
1219 (event == CH_EVENT_UC_RSRESET))) {
1220 fsm_newstate(fi, CH_STATE_STARTRETRY);
1221 fsm_deltimer(&ch->timer);
1222 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
1223 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1224 int rc = ccw_device_halt(ch->cdev, (unsigned long) ch);
1225 if (rc != 0)
1226 ccw_check_return_code(
1227 ch, rc, "HaltIO in ch_action_setuperr");
1228 }
1229 return;
1230 }
1231
1232 ctc_pr_debug("%s: Error %s during %s channel setup state=%s\n",
1233 dev->name, ch_event_names[event],
1234 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX",
1235 fsm_getstate_str(fi));
1236 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1237 fsm_newstate(fi, CH_STATE_RXERR);
1238 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1239 DEV_EVENT_RXDOWN, dev);
1240 } else {
1241 fsm_newstate(fi, CH_STATE_TXERR);
1242 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1243 DEV_EVENT_TXDOWN, dev);
1244 }
1245}
1246
1247/**
1248 * Restart a channel after an error.
1249 *
1250 * @param fi An instance of a channel statemachine.
1251 * @param event The event, just happened.
1252 * @param arg Generic pointer, casted from channel * upon call.
1253 */
1254static void
1255ch_action_restart(fsm_instance * fi, int event, void *arg)
1256{
1257 unsigned long saveflags;
1258 int oldstate;
1259 int rc;
1260
1261 struct channel *ch = (struct channel *) arg;
1262 struct net_device *dev = ch->netdev;
1263
1264 DBF_TEXT(trace, 3, __FUNCTION__);
1265 fsm_deltimer(&ch->timer);
1266 ctc_pr_debug("%s: %s channel restart\n", dev->name,
1267 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
1268 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
1269 oldstate = fsm_getstate(fi);
1270 fsm_newstate(fi, CH_STATE_STARTWAIT);
1271 saveflags = 0; /* avoids compiler warning with
1272 spin_unlock_irqrestore */
1273 if (event == CH_EVENT_TIMER) // only for timer not yet locked
1274 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
1275 rc = ccw_device_halt(ch->cdev, (unsigned long) ch);
1276 if (event == CH_EVENT_TIMER)
1277 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
1278 if (rc != 0) {
1279 if (rc != -EBUSY) {
1280 fsm_deltimer(&ch->timer);
1281 fsm_newstate(fi, oldstate);
1282 }
1283 ccw_check_return_code(ch, rc, "HaltIO in ch_action_restart");
1284 }
1285}
1286
1287/**
1288 * Handle error during RX initial handshake (exchange of
1289 * 0-length block header)
1290 *
1291 * @param fi An instance of a channel statemachine.
1292 * @param event The event, just happened.
1293 * @param arg Generic pointer, casted from channel * upon call.
1294 */
1295static void
1296ch_action_rxiniterr(fsm_instance * fi, int event, void *arg)
1297{
1298 struct channel *ch = (struct channel *) arg;
1299 struct net_device *dev = ch->netdev;
1300
1301 DBF_TEXT(setup, 3, __FUNCTION__);
1302 if (event == CH_EVENT_TIMER) {
1303 fsm_deltimer(&ch->timer);
1304 ctc_pr_debug("%s: Timeout during RX init handshake\n", dev->name);
1305 if (ch->retry++ < 3)
1306 ch_action_restart(fi, event, arg);
1307 else {
1308 fsm_newstate(fi, CH_STATE_RXERR);
1309 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1310 DEV_EVENT_RXDOWN, dev);
1311 }
1312 } else
1313 ctc_pr_warn("%s: Error during RX init handshake\n", dev->name);
1314}
1315
1316/**
1317 * Notify device statemachine if we gave up initialization
1318 * of RX channel.
1319 *
1320 * @param fi An instance of a channel statemachine.
1321 * @param event The event, just happened.
1322 * @param arg Generic pointer, casted from channel * upon call.
1323 */
1324static void
1325ch_action_rxinitfail(fsm_instance * fi, int event, void *arg)
1326{
1327 struct channel *ch = (struct channel *) arg;
1328 struct net_device *dev = ch->netdev;
1329
1330 DBF_TEXT(setup, 3, __FUNCTION__);
1331 fsm_newstate(fi, CH_STATE_RXERR);
1332 ctc_pr_warn("%s: RX initialization failed\n", dev->name);
1333 ctc_pr_warn("%s: RX <-> RX connection detected\n", dev->name);
1334 fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
1335}
1336
1337/**
1338 * Handle RX Unit check remote reset (remote disconnected)
1339 *
1340 * @param fi An instance of a channel statemachine.
1341 * @param event The event, just happened.
1342 * @param arg Generic pointer, casted from channel * upon call.
1343 */
1344static void
1345ch_action_rxdisc(fsm_instance * fi, int event, void *arg)
1346{
1347 struct channel *ch = (struct channel *) arg;
1348 struct channel *ch2;
1349 struct net_device *dev = ch->netdev;
1350
1351 DBF_TEXT(trace, 3, __FUNCTION__);
1352 fsm_deltimer(&ch->timer);
1353 ctc_pr_debug("%s: Got remote disconnect, re-initializing ...\n",
1354 dev->name);
1355
1356 /**
1357 * Notify device statemachine
1358 */
1359 fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
1360 fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
1361
1362 fsm_newstate(fi, CH_STATE_DTERM);
1363 ch2 = ((struct ctc_priv *) dev->priv)->channel[WRITE];
1364 fsm_newstate(ch2->fsm, CH_STATE_DTERM);
1365
1366 ccw_device_halt(ch->cdev, (unsigned long) ch);
1367 ccw_device_halt(ch2->cdev, (unsigned long) ch2);
1368}
1369
1370/**
1371 * Handle error during TX channel initialization.
1372 *
1373 * @param fi An instance of a channel statemachine.
1374 * @param event The event, just happened.
1375 * @param arg Generic pointer, casted from channel * upon call.
1376 */
1377static void
1378ch_action_txiniterr(fsm_instance * fi, int event, void *arg)
1379{
1380 struct channel *ch = (struct channel *) arg;
1381 struct net_device *dev = ch->netdev;
1382
1383 DBF_TEXT(setup, 2, __FUNCTION__);
1384 if (event == CH_EVENT_TIMER) {
1385 fsm_deltimer(&ch->timer);
1386 ctc_pr_debug("%s: Timeout during TX init handshake\n", dev->name);
1387 if (ch->retry++ < 3)
1388 ch_action_restart(fi, event, arg);
1389 else {
1390 fsm_newstate(fi, CH_STATE_TXERR);
1391 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1392 DEV_EVENT_TXDOWN, dev);
1393 }
1394 } else
1395 ctc_pr_warn("%s: Error during TX init handshake\n", dev->name);
1396}
1397
1398/**
1399 * Handle TX timeout by retrying operation.
1400 *
1401 * @param fi An instance of a channel statemachine.
1402 * @param event The event, just happened.
1403 * @param arg Generic pointer, casted from channel * upon call.
1404 */
1405static void
1406ch_action_txretry(fsm_instance * fi, int event, void *arg)
1407{
1408 struct channel *ch = (struct channel *) arg;
1409 struct net_device *dev = ch->netdev;
1410 unsigned long saveflags;
1411
1412 DBF_TEXT(trace, 4, __FUNCTION__);
1413 fsm_deltimer(&ch->timer);
1414 if (ch->retry++ > 3) {
1415 ctc_pr_debug("%s: TX retry failed, restarting channel\n",
1416 dev->name);
1417 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1418 DEV_EVENT_TXDOWN, dev);
1419 ch_action_restart(fi, event, arg);
1420 } else {
1421 struct sk_buff *skb;
1422
1423 ctc_pr_debug("%s: TX retry %d\n", dev->name, ch->retry);
1424 if ((skb = skb_peek(&ch->io_queue))) {
1425 int rc = 0;
1426
1427 clear_normalized_cda(&ch->ccw[4]);
1428 ch->ccw[4].count = skb->len;
1429 if (set_normalized_cda(&ch->ccw[4], skb->data)) {
1430 ctc_pr_debug(
1431 "%s: IDAL alloc failed, chan restart\n",
1432 dev->name);
1433 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1434 DEV_EVENT_TXDOWN, dev);
1435 ch_action_restart(fi, event, arg);
1436 return;
1437 }
1438 fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch);
1439 saveflags = 0; /* avoids compiler warning with
1440 spin_unlock_irqrestore */
1441 if (event == CH_EVENT_TIMER) // only for TIMER not yet locked
1442 spin_lock_irqsave(get_ccwdev_lock(ch->cdev),
1443 saveflags);
1444 rc = ccw_device_start(ch->cdev, &ch->ccw[3],
1445 (unsigned long) ch, 0xff, 0);
1446 if (event == CH_EVENT_TIMER)
1447 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev),
1448 saveflags);
1449 if (rc != 0) {
1450 fsm_deltimer(&ch->timer);
1451 ccw_check_return_code(ch, rc, "TX in ch_action_txretry");
1452 ctc_purge_skb_queue(&ch->io_queue);
1453 }
1454 }
1455 }
1456
1457}
1458
1459/**
1460 * Handle fatal errors during an I/O command.
1461 *
1462 * @param fi An instance of a channel statemachine.
1463 * @param event The event, just happened.
1464 * @param arg Generic pointer, casted from channel * upon call.
1465 */
1466static void
1467ch_action_iofatal(fsm_instance * fi, int event, void *arg)
1468{
1469 struct channel *ch = (struct channel *) arg;
1470 struct net_device *dev = ch->netdev;
1471
1472 DBF_TEXT(trace, 3, __FUNCTION__);
1473 fsm_deltimer(&ch->timer);
1474 if (CHANNEL_DIRECTION(ch->flags) == READ) {
1475 ctc_pr_debug("%s: RX I/O error\n", dev->name);
1476 fsm_newstate(fi, CH_STATE_RXERR);
1477 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1478 DEV_EVENT_RXDOWN, dev);
1479 } else {
1480 ctc_pr_debug("%s: TX I/O error\n", dev->name);
1481 fsm_newstate(fi, CH_STATE_TXERR);
1482 fsm_event(((struct ctc_priv *) dev->priv)->fsm,
1483 DEV_EVENT_TXDOWN, dev);
1484 }
1485}
1486
1487static void
1488ch_action_reinit(fsm_instance *fi, int event, void *arg)
1489{
1490 struct channel *ch = (struct channel *)arg;
1491 struct net_device *dev = ch->netdev;
1492 struct ctc_priv *privptr = dev->priv;
1493
1494 DBF_TEXT(trace, 4, __FUNCTION__);
1495 ch_action_iofatal(fi, event, arg);
1496 fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
1497}
1498
1499/**
1500 * The statemachine for a channel.
1501 */
1502static const fsm_node ch_fsm[] = {
1503 {CH_STATE_STOPPED, CH_EVENT_STOP, fsm_action_nop },
1504 {CH_STATE_STOPPED, CH_EVENT_START, ch_action_start },
1505 {CH_STATE_STOPPED, CH_EVENT_FINSTAT, fsm_action_nop },
1506 {CH_STATE_STOPPED, CH_EVENT_MC_FAIL, fsm_action_nop },
1507
1508 {CH_STATE_NOTOP, CH_EVENT_STOP, ch_action_stop },
1509 {CH_STATE_NOTOP, CH_EVENT_START, fsm_action_nop },
1510 {CH_STATE_NOTOP, CH_EVENT_FINSTAT, fsm_action_nop },
1511 {CH_STATE_NOTOP, CH_EVENT_MC_FAIL, fsm_action_nop },
1512 {CH_STATE_NOTOP, CH_EVENT_MC_GOOD, ch_action_start },
1513
1514 {CH_STATE_STARTWAIT, CH_EVENT_STOP, ch_action_haltio },
1515 {CH_STATE_STARTWAIT, CH_EVENT_START, fsm_action_nop },
1516 {CH_STATE_STARTWAIT, CH_EVENT_FINSTAT, ch_action_setmode },
1517 {CH_STATE_STARTWAIT, CH_EVENT_TIMER, ch_action_setuperr },
1518 {CH_STATE_STARTWAIT, CH_EVENT_IO_ENODEV, ch_action_iofatal },
1519 {CH_STATE_STARTWAIT, CH_EVENT_IO_EIO, ch_action_reinit },
1520 {CH_STATE_STARTWAIT, CH_EVENT_MC_FAIL, ch_action_fail },
1521
1522 {CH_STATE_STARTRETRY, CH_EVENT_STOP, ch_action_haltio },
1523 {CH_STATE_STARTRETRY, CH_EVENT_TIMER, ch_action_setmode },
1524 {CH_STATE_STARTRETRY, CH_EVENT_FINSTAT, fsm_action_nop },
1525 {CH_STATE_STARTRETRY, CH_EVENT_MC_FAIL, ch_action_fail },
1526
1527 {CH_STATE_SETUPWAIT, CH_EVENT_STOP, ch_action_haltio },
1528 {CH_STATE_SETUPWAIT, CH_EVENT_START, fsm_action_nop },
1529 {CH_STATE_SETUPWAIT, CH_EVENT_FINSTAT, ch_action_firstio },
1530 {CH_STATE_SETUPWAIT, CH_EVENT_UC_RCRESET, ch_action_setuperr },
1531 {CH_STATE_SETUPWAIT, CH_EVENT_UC_RSRESET, ch_action_setuperr },
1532 {CH_STATE_SETUPWAIT, CH_EVENT_TIMER, ch_action_setmode },
1533 {CH_STATE_SETUPWAIT, CH_EVENT_IO_ENODEV, ch_action_iofatal },
1534 {CH_STATE_SETUPWAIT, CH_EVENT_IO_EIO, ch_action_reinit },
1535 {CH_STATE_SETUPWAIT, CH_EVENT_MC_FAIL, ch_action_fail },
1536
1537 {CH_STATE_RXINIT, CH_EVENT_STOP, ch_action_haltio },
1538 {CH_STATE_RXINIT, CH_EVENT_START, fsm_action_nop },
1539 {CH_STATE_RXINIT, CH_EVENT_FINSTAT, ch_action_rxidle },
1540 {CH_STATE_RXINIT, CH_EVENT_UC_RCRESET, ch_action_rxiniterr },
1541 {CH_STATE_RXINIT, CH_EVENT_UC_RSRESET, ch_action_rxiniterr },
1542 {CH_STATE_RXINIT, CH_EVENT_TIMER, ch_action_rxiniterr },
1543 {CH_STATE_RXINIT, CH_EVENT_ATTNBUSY, ch_action_rxinitfail },
1544 {CH_STATE_RXINIT, CH_EVENT_IO_ENODEV, ch_action_iofatal },
1545 {CH_STATE_RXINIT, CH_EVENT_IO_EIO, ch_action_reinit },
1546 {CH_STATE_RXINIT, CH_EVENT_UC_ZERO, ch_action_firstio },
1547 {CH_STATE_RXINIT, CH_EVENT_MC_FAIL, ch_action_fail },
1548
1549 {CH_STATE_RXIDLE, CH_EVENT_STOP, ch_action_haltio },
1550 {CH_STATE_RXIDLE, CH_EVENT_START, fsm_action_nop },
1551 {CH_STATE_RXIDLE, CH_EVENT_FINSTAT, ch_action_rx },
1552 {CH_STATE_RXIDLE, CH_EVENT_UC_RCRESET, ch_action_rxdisc },
1553// {CH_STATE_RXIDLE, CH_EVENT_UC_RSRESET, ch_action_rxretry },
1554 {CH_STATE_RXIDLE, CH_EVENT_IO_ENODEV, ch_action_iofatal },
1555 {CH_STATE_RXIDLE, CH_EVENT_IO_EIO, ch_action_reinit },
1556 {CH_STATE_RXIDLE, CH_EVENT_MC_FAIL, ch_action_fail },
1557 {CH_STATE_RXIDLE, CH_EVENT_UC_ZERO, ch_action_rx },
1558
1559 {CH_STATE_TXINIT, CH_EVENT_STOP, ch_action_haltio },
1560 {CH_STATE_TXINIT, CH_EVENT_START, fsm_action_nop },
1561 {CH_STATE_TXINIT, CH_EVENT_FINSTAT, ch_action_txidle },
1562 {CH_STATE_TXINIT, CH_EVENT_UC_RCRESET, ch_action_txiniterr },
1563 {CH_STATE_TXINIT, CH_EVENT_UC_RSRESET, ch_action_txiniterr },
1564 {CH_STATE_TXINIT, CH_EVENT_TIMER, ch_action_txiniterr },
1565 {CH_STATE_TXINIT, CH_EVENT_IO_ENODEV, ch_action_iofatal },
1566 {CH_STATE_TXINIT, CH_EVENT_IO_EIO, ch_action_reinit },
1567 {CH_STATE_TXINIT, CH_EVENT_MC_FAIL, ch_action_fail },
1568
1569 {CH_STATE_TXIDLE, CH_EVENT_STOP, ch_action_haltio },
1570 {CH_STATE_TXIDLE, CH_EVENT_START, fsm_action_nop },
1571 {CH_STATE_TXIDLE, CH_EVENT_FINSTAT, ch_action_firstio },
1572 {CH_STATE_TXIDLE, CH_EVENT_UC_RCRESET, fsm_action_nop },
1573 {CH_STATE_TXIDLE, CH_EVENT_UC_RSRESET, fsm_action_nop },
1574 {CH_STATE_TXIDLE, CH_EVENT_IO_ENODEV, ch_action_iofatal },
1575 {CH_STATE_TXIDLE, CH_EVENT_IO_EIO, ch_action_reinit },
1576 {CH_STATE_TXIDLE, CH_EVENT_MC_FAIL, ch_action_fail },
1577
1578 {CH_STATE_TERM, CH_EVENT_STOP, fsm_action_nop },
1579 {CH_STATE_TERM, CH_EVENT_START, ch_action_restart },
1580 {CH_STATE_TERM, CH_EVENT_FINSTAT, ch_action_stopped },
1581 {CH_STATE_TERM, CH_EVENT_UC_RCRESET, fsm_action_nop },
1582 {CH_STATE_TERM, CH_EVENT_UC_RSRESET, fsm_action_nop },
1583 {CH_STATE_TERM, CH_EVENT_MC_FAIL, ch_action_fail },
1584
1585 {CH_STATE_DTERM, CH_EVENT_STOP, ch_action_haltio },
1586 {CH_STATE_DTERM, CH_EVENT_START, ch_action_restart },
1587 {CH_STATE_DTERM, CH_EVENT_FINSTAT, ch_action_setmode },
1588 {CH_STATE_DTERM, CH_EVENT_UC_RCRESET, fsm_action_nop },
1589 {CH_STATE_DTERM, CH_EVENT_UC_RSRESET, fsm_action_nop },
1590 {CH_STATE_DTERM, CH_EVENT_MC_FAIL, ch_action_fail },
1591
1592 {CH_STATE_TX, CH_EVENT_STOP, ch_action_haltio },
1593 {CH_STATE_TX, CH_EVENT_START, fsm_action_nop },
1594 {CH_STATE_TX, CH_EVENT_FINSTAT, ch_action_txdone },
1595 {CH_STATE_TX, CH_EVENT_UC_RCRESET, ch_action_txretry },
1596 {CH_STATE_TX, CH_EVENT_UC_RSRESET, ch_action_txretry },
1597 {CH_STATE_TX, CH_EVENT_TIMER, ch_action_txretry },
1598 {CH_STATE_TX, CH_EVENT_IO_ENODEV, ch_action_iofatal },
1599 {CH_STATE_TX, CH_EVENT_IO_EIO, ch_action_reinit },
1600 {CH_STATE_TX, CH_EVENT_MC_FAIL, ch_action_fail },
1601
1602 {CH_STATE_RXERR, CH_EVENT_STOP, ch_action_haltio },
1603 {CH_STATE_TXERR, CH_EVENT_STOP, ch_action_haltio },
1604 {CH_STATE_TXERR, CH_EVENT_MC_FAIL, ch_action_fail },
1605 {CH_STATE_RXERR, CH_EVENT_MC_FAIL, ch_action_fail },
1606};
1607
1608static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node);
1609
1610/**
1611 * Functions related to setup and device detection.
1612 *****************************************************************************/
1613
1614static inline int
1615less_than(char *id1, char *id2)
1616{
1617 int dev1, dev2, i;
1618
1619 for (i = 0; i < 5; i++) {
1620 id1++;
1621 id2++;
1622 }
1623 dev1 = simple_strtoul(id1, &id1, 16);
1624 dev2 = simple_strtoul(id2, &id2, 16);
1625
1626 return (dev1 < dev2);
1627}
1628
1629/**
1630 * Add a new channel to the list of channels.
1631 * Keeps the channel list sorted.
1632 *
1633 * @param cdev The ccw_device to be added.
1634 * @param type The type class of the new channel.
1635 *
1636 * @return 0 on success, !0 on error.
1637 */
1638static int
1639add_channel(struct ccw_device *cdev, enum channel_types type)
1640{
1641 struct channel **c = &channels;
1642 struct channel *ch;
1643
1644 DBF_TEXT(trace, 2, __FUNCTION__);
1645 ch = kzalloc(sizeof(struct channel), GFP_KERNEL);
1646 if (!ch) {
1647 ctc_pr_warn("ctc: Out of memory in add_channel\n");
1648 return -1;
1649 }
1650 /* assure all flags and counters are reset */
1651 ch->ccw = kzalloc(8 * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
1652 if (!ch->ccw) {
1653 kfree(ch);
1654 ctc_pr_warn("ctc: Out of memory in add_channel\n");
1655 return -1;
1656 }
1657
1658
1659 /**
1660 * "static" ccws are used in the following way:
1661 *
1662 * ccw[0..2] (Channel program for generic I/O):
1663 * 0: prepare
1664 * 1: read or write (depending on direction) with fixed
1665 * buffer (idal allocated once when buffer is allocated)
1666 * 2: nop
1667 * ccw[3..5] (Channel program for direct write of packets)
1668 * 3: prepare
1669 * 4: write (idal allocated on every write).
1670 * 5: nop
1671 * ccw[6..7] (Channel program for initial channel setup):
1672 * 6: set extended mode
1673 * 7: nop
1674 *
1675 * ch->ccw[0..5] are initialized in ch_action_start because
1676 * the channel's direction is yet unknown here.
1677 */
1678 ch->ccw[6].cmd_code = CCW_CMD_SET_EXTENDED;
1679 ch->ccw[6].flags = CCW_FLAG_SLI;
1680
1681 ch->ccw[7].cmd_code = CCW_CMD_NOOP;
1682 ch->ccw[7].flags = CCW_FLAG_SLI;
1683
1684 ch->cdev = cdev;
1685 snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id);
1686 ch->type = type;
1687 ch->fsm = init_fsm(ch->id, ch_state_names,
1688 ch_event_names, NR_CH_STATES, NR_CH_EVENTS,
1689 ch_fsm, CH_FSM_LEN, GFP_KERNEL);
1690 if (ch->fsm == NULL) {
1691 ctc_pr_warn("ctc: Could not create FSM in add_channel\n");
1692 kfree(ch->ccw);
1693 kfree(ch);
1694 return -1;
1695 }
1696 fsm_newstate(ch->fsm, CH_STATE_IDLE);
1697 ch->irb = kzalloc(sizeof(struct irb), GFP_KERNEL);
1698 if (!ch->irb) {
1699 ctc_pr_warn("ctc: Out of memory in add_channel\n");
1700 kfree_fsm(ch->fsm);
1701 kfree(ch->ccw);
1702 kfree(ch);
1703 return -1;
1704 }
1705 while (*c && less_than((*c)->id, ch->id))
1706 c = &(*c)->next;
1707 if (*c && (!strncmp((*c)->id, ch->id, CTC_ID_SIZE))) {
1708 ctc_pr_debug(
1709 "ctc: add_channel: device %s already in list, "
1710 "using old entry\n", (*c)->id);
1711 kfree(ch->irb);
1712 kfree_fsm(ch->fsm);
1713 kfree(ch->ccw);
1714 kfree(ch);
1715 return 0;
1716 }
1717
1718 spin_lock_init(&ch->collect_lock);
1719
1720 fsm_settimer(ch->fsm, &ch->timer);
1721 skb_queue_head_init(&ch->io_queue);
1722 skb_queue_head_init(&ch->collect_queue);
1723 ch->next = *c;
1724 *c = ch;
1725 return 0;
1726}
1727
1728/**
1729 * Release a specific channel in the channel list.
1730 *
1731 * @param ch Pointer to channel struct to be released.
1732 */
1733static void
1734channel_free(struct channel *ch)
1735{
1736 ch->flags &= ~CHANNEL_FLAGS_INUSE;
1737 fsm_newstate(ch->fsm, CH_STATE_IDLE);
1738}
1739
1740/**
1741 * Remove a specific channel in the channel list.
1742 *
1743 * @param ch Pointer to channel struct to be released.
1744 */
1745static void
1746channel_remove(struct channel *ch)
1747{
1748 struct channel **c = &channels;
1749
1750 DBF_TEXT(trace, 2, __FUNCTION__);
1751 if (ch == NULL)
1752 return;
1753
1754 channel_free(ch);
1755 while (*c) {
1756 if (*c == ch) {
1757 *c = ch->next;
1758 fsm_deltimer(&ch->timer);
1759 kfree_fsm(ch->fsm);
1760 clear_normalized_cda(&ch->ccw[4]);
1761 if (ch->trans_skb != NULL) {
1762 clear_normalized_cda(&ch->ccw[1]);
1763 dev_kfree_skb(ch->trans_skb);
1764 }
1765 kfree(ch->ccw);
1766 kfree(ch->irb);
1767 kfree(ch);
1768 return;
1769 }
1770 c = &((*c)->next);
1771 }
1772}
1773
1774/**
1775 * Get a specific channel from the channel list.
1776 *
1777 * @param type Type of channel we are interested in.
1778 * @param id Id of channel we are interested in.
1779 * @param direction Direction we want to use this channel for.
1780 *
1781 * @return Pointer to a channel or NULL if no matching channel available.
1782 */
1783static struct channel
1784*
1785channel_get(enum channel_types type, char *id, int direction)
1786{
1787 struct channel *ch = channels;
1788
1789 DBF_TEXT(trace, 3, __FUNCTION__);
1790#ifdef DEBUG
1791 ctc_pr_debug("ctc: %s(): searching for ch with id %s and type %d\n",
1792 __func__, id, type);
1793#endif
1794
1795 while (ch && ((strncmp(ch->id, id, CTC_ID_SIZE)) || (ch->type != type))) {
1796#ifdef DEBUG
1797 ctc_pr_debug("ctc: %s(): ch=0x%p (id=%s, type=%d\n",
1798 __func__, ch, ch->id, ch->type);
1799#endif
1800 ch = ch->next;
1801 }
1802#ifdef DEBUG
1803 ctc_pr_debug("ctc: %s(): ch=0x%pq (id=%s, type=%d\n",
1804 __func__, ch, ch->id, ch->type);
1805#endif
1806 if (!ch) {
1807 ctc_pr_warn("ctc: %s(): channel with id %s "
1808 "and type %d not found in channel list\n",
1809 __func__, id, type);
1810 } else {
1811 if (ch->flags & CHANNEL_FLAGS_INUSE)
1812 ch = NULL;
1813 else {
1814 ch->flags |= CHANNEL_FLAGS_INUSE;
1815 ch->flags &= ~CHANNEL_FLAGS_RWMASK;
1816 ch->flags |= (direction == WRITE)
1817 ? CHANNEL_FLAGS_WRITE : CHANNEL_FLAGS_READ;
1818 fsm_newstate(ch->fsm, CH_STATE_STOPPED);
1819 }
1820 }
1821 return ch;
1822}
1823
1824/**
1825 * Return the channel type by name.
1826 *
1827 * @param name Name of network interface.
1828 *
1829 * @return Type class of channel to be used for that interface.
1830 */
1831static enum channel_types inline
1832extract_channel_media(char *name)
1833{
1834 enum channel_types ret = channel_type_unknown;
1835
1836 if (name != NULL) {
1837 if (strncmp(name, "ctc", 3) == 0)
1838 ret = channel_type_parallel;
1839 if (strncmp(name, "escon", 5) == 0)
1840 ret = channel_type_escon;
1841 }
1842 return ret;
1843}
1844
1845static long
1846__ctc_check_irb_error(struct ccw_device *cdev, struct irb *irb)
1847{
1848 if (!IS_ERR(irb))
1849 return 0;
1850
1851 switch (PTR_ERR(irb)) {
1852 case -EIO:
1853 ctc_pr_warn("i/o-error on device %s\n", cdev->dev.bus_id);
1854// CTC_DBF_TEXT(trace, 2, "ckirberr");
1855// CTC_DBF_TEXT_(trace, 2, " rc%d", -EIO);
1856 break;
1857 case -ETIMEDOUT:
1858 ctc_pr_warn("timeout on device %s\n", cdev->dev.bus_id);
1859// CTC_DBF_TEXT(trace, 2, "ckirberr");
1860// CTC_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT);
1861 break;
1862 default:
1863 ctc_pr_warn("unknown error %ld on device %s\n", PTR_ERR(irb),
1864 cdev->dev.bus_id);
1865// CTC_DBF_TEXT(trace, 2, "ckirberr");
1866// CTC_DBF_TEXT(trace, 2, " rc???");
1867 }
1868 return PTR_ERR(irb);
1869}
1870
1871/**
1872 * Main IRQ handler.
1873 *
1874 * @param cdev The ccw_device the interrupt is for.
1875 * @param intparm interruption parameter.
1876 * @param irb interruption response block.
1877 */
1878static void
1879ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1880{
1881 struct channel *ch;
1882 struct net_device *dev;
1883 struct ctc_priv *priv;
1884
1885 DBF_TEXT(trace, 5, __FUNCTION__);
1886 if (__ctc_check_irb_error(cdev, irb))
1887 return;
1888
1889 /* Check for unsolicited interrupts. */
1890 if (!cdev->dev.driver_data) {
1891 ctc_pr_warn("ctc: Got unsolicited irq: %s c-%02x d-%02x\n",
1892 cdev->dev.bus_id, irb->scsw.cstat,
1893 irb->scsw.dstat);
1894 return;
1895 }
1896
1897 priv = ((struct ccwgroup_device *)cdev->dev.driver_data)
1898 ->dev.driver_data;
1899
1900 /* Try to extract channel from driver data. */
1901 if (priv->channel[READ]->cdev == cdev)
1902 ch = priv->channel[READ];
1903 else if (priv->channel[WRITE]->cdev == cdev)
1904 ch = priv->channel[WRITE];
1905 else {
1906 ctc_pr_err("ctc: Can't determine channel for interrupt, "
1907 "device %s\n", cdev->dev.bus_id);
1908 return;
1909 }
1910
1911 dev = (struct net_device *) (ch->netdev);
1912 if (dev == NULL) {
1913 ctc_pr_crit("ctc: ctc_irq_handler dev=NULL bus_id=%s, ch=0x%p\n",
1914 cdev->dev.bus_id, ch);
1915 return;
1916 }
1917
1918#ifdef DEBUG
1919 ctc_pr_debug("%s: interrupt for device: %s received c-%02x d-%02x\n",
1920 dev->name, ch->id, irb->scsw.cstat, irb->scsw.dstat);
1921#endif
1922
1923 /* Copy interruption response block. */
1924 memcpy(ch->irb, irb, sizeof(struct irb));
1925
1926 /* Check for good subchannel return code, otherwise error message */
1927 if (ch->irb->scsw.cstat) {
1928 fsm_event(ch->fsm, CH_EVENT_SC_UNKNOWN, ch);
1929 ctc_pr_warn("%s: subchannel check for device: %s - %02x %02x\n",
1930 dev->name, ch->id, ch->irb->scsw.cstat,
1931 ch->irb->scsw.dstat);
1932 return;
1933 }
1934
1935 /* Check the reason-code of a unit check */
1936 if (ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {
1937 ccw_unit_check(ch, ch->irb->ecw[0]);
1938 return;
1939 }
1940 if (ch->irb->scsw.dstat & DEV_STAT_BUSY) {
1941 if (ch->irb->scsw.dstat & DEV_STAT_ATTENTION)
1942 fsm_event(ch->fsm, CH_EVENT_ATTNBUSY, ch);
1943 else
1944 fsm_event(ch->fsm, CH_EVENT_BUSY, ch);
1945 return;
1946 }
1947 if (ch->irb->scsw.dstat & DEV_STAT_ATTENTION) {
1948 fsm_event(ch->fsm, CH_EVENT_ATTN, ch);
1949 return;
1950 }
1951 if ((ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) ||
1952 (ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) ||
1953 (ch->irb->scsw.stctl ==
1954 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))
1955 fsm_event(ch->fsm, CH_EVENT_FINSTAT, ch);
1956 else
1957 fsm_event(ch->fsm, CH_EVENT_IRQ, ch);
1958
1959}
1960
1961/**
1962 * Actions for interface - statemachine.
1963 *****************************************************************************/
1964
1965/**
1966 * Startup channels by sending CH_EVENT_START to each channel.
1967 *
1968 * @param fi An instance of an interface statemachine.
1969 * @param event The event, just happened.
1970 * @param arg Generic pointer, casted from struct net_device * upon call.
1971 */
1972static void
1973dev_action_start(fsm_instance * fi, int event, void *arg)
1974{
1975 struct net_device *dev = (struct net_device *) arg;
1976 struct ctc_priv *privptr = dev->priv;
1977 int direction;
1978
1979 DBF_TEXT(setup, 3, __FUNCTION__);
1980 fsm_deltimer(&privptr->restart_timer);
1981 fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
1982 for (direction = READ; direction <= WRITE; direction++) {
1983 struct channel *ch = privptr->channel[direction];
1984 fsm_event(ch->fsm, CH_EVENT_START, ch);
1985 }
1986}
1987
1988/**
1989 * Shutdown channels by sending CH_EVENT_STOP to each channel.
1990 *
1991 * @param fi An instance of an interface statemachine.
1992 * @param event The event, just happened.
1993 * @param arg Generic pointer, casted from struct net_device * upon call.
1994 */
1995static void
1996dev_action_stop(fsm_instance * fi, int event, void *arg)
1997{
1998 struct net_device *dev = (struct net_device *) arg;
1999 struct ctc_priv *privptr = dev->priv;
2000 int direction;
2001
2002 DBF_TEXT(trace, 3, __FUNCTION__);
2003 fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
2004 for (direction = READ; direction <= WRITE; direction++) {
2005 struct channel *ch = privptr->channel[direction];
2006 fsm_event(ch->fsm, CH_EVENT_STOP, ch);
2007 }
2008}
2009static void
2010dev_action_restart(fsm_instance *fi, int event, void *arg)
2011{
2012 struct net_device *dev = (struct net_device *)arg;
2013 struct ctc_priv *privptr = dev->priv;
2014
2015 DBF_TEXT(trace, 3, __FUNCTION__);
2016 ctc_pr_debug("%s: Restarting\n", dev->name);
2017 dev_action_stop(fi, event, arg);
2018 fsm_event(privptr->fsm, DEV_EVENT_STOP, dev);
2019 fsm_addtimer(&privptr->restart_timer, CTC_TIMEOUT_5SEC,
2020 DEV_EVENT_START, dev);
2021}
2022
2023/**
2024 * Called from channel statemachine
2025 * when a channel is up and running.
2026 *
2027 * @param fi An instance of an interface statemachine.
2028 * @param event The event, just happened.
2029 * @param arg Generic pointer, casted from struct net_device * upon call.
2030 */
2031static void
2032dev_action_chup(fsm_instance * fi, int event, void *arg)
2033{
2034 struct net_device *dev = (struct net_device *) arg;
2035
2036 DBF_TEXT(trace, 3, __FUNCTION__);
2037 switch (fsm_getstate(fi)) {
2038 case DEV_STATE_STARTWAIT_RXTX:
2039 if (event == DEV_EVENT_RXUP)
2040 fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
2041 else
2042 fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
2043 break;
2044 case DEV_STATE_STARTWAIT_RX:
2045 if (event == DEV_EVENT_RXUP) {
2046 fsm_newstate(fi, DEV_STATE_RUNNING);
2047 ctc_pr_info("%s: connected with remote side\n",
2048 dev->name);
2049 ctc_clear_busy(dev);
2050 }
2051 break;
2052 case DEV_STATE_STARTWAIT_TX:
2053 if (event == DEV_EVENT_TXUP) {
2054 fsm_newstate(fi, DEV_STATE_RUNNING);
2055 ctc_pr_info("%s: connected with remote side\n",
2056 dev->name);
2057 ctc_clear_busy(dev);
2058 }
2059 break;
2060 case DEV_STATE_STOPWAIT_TX:
2061 if (event == DEV_EVENT_RXUP)
2062 fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
2063 break;
2064 case DEV_STATE_STOPWAIT_RX:
2065 if (event == DEV_EVENT_TXUP)
2066 fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
2067 break;
2068 }
2069}
2070
2071/**
2072 * Called from channel statemachine
2073 * when a channel has been shutdown.
2074 *
2075 * @param fi An instance of an interface statemachine.
2076 * @param event The event, just happened.
2077 * @param arg Generic pointer, casted from struct net_device * upon call.
2078 */
2079static void
2080dev_action_chdown(fsm_instance * fi, int event, void *arg)
2081{
2082
2083 DBF_TEXT(trace, 3, __FUNCTION__);
2084 switch (fsm_getstate(fi)) {
2085 case DEV_STATE_RUNNING:
2086 if (event == DEV_EVENT_TXDOWN)
2087 fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
2088 else
2089 fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
2090 break;
2091 case DEV_STATE_STARTWAIT_RX:
2092 if (event == DEV_EVENT_TXDOWN)
2093 fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
2094 break;
2095 case DEV_STATE_STARTWAIT_TX:
2096 if (event == DEV_EVENT_RXDOWN)
2097 fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
2098 break;
2099 case DEV_STATE_STOPWAIT_RXTX:
2100 if (event == DEV_EVENT_TXDOWN)
2101 fsm_newstate(fi, DEV_STATE_STOPWAIT_RX);
2102 else
2103 fsm_newstate(fi, DEV_STATE_STOPWAIT_TX);
2104 break;
2105 case DEV_STATE_STOPWAIT_RX:
2106 if (event == DEV_EVENT_RXDOWN)
2107 fsm_newstate(fi, DEV_STATE_STOPPED);
2108 break;
2109 case DEV_STATE_STOPWAIT_TX:
2110 if (event == DEV_EVENT_TXDOWN)
2111 fsm_newstate(fi, DEV_STATE_STOPPED);
2112 break;
2113 }
2114}
2115
2116static const fsm_node dev_fsm[] = {
2117 {DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start},
2118
2119 {DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_START, dev_action_start },
2120 {DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown },
2121 {DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown },
2122 {DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },
2123
2124 {DEV_STATE_STOPWAIT_RX, DEV_EVENT_START, dev_action_start },
2125 {DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXUP, dev_action_chup },
2126 {DEV_STATE_STOPWAIT_RX, DEV_EVENT_TXUP, dev_action_chup },
2127 {DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXDOWN, dev_action_chdown },
2128 {DEV_STATE_STOPWAIT_RX, DEV_EVENT_RESTART, dev_action_restart },
2129
2130 {DEV_STATE_STOPWAIT_TX, DEV_EVENT_START, dev_action_start },
2131 {DEV_STATE_STOPWAIT_TX, DEV_EVENT_RXUP, dev_action_chup },
2132 {DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXUP, dev_action_chup },
2133 {DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXDOWN, dev_action_chdown },
2134 {DEV_STATE_STOPWAIT_TX, DEV_EVENT_RESTART, dev_action_restart },
2135
2136 {DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP, dev_action_stop },
2137 {DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP, dev_action_chup },
2138 {DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP, dev_action_chup },
2139 {DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown },
2140 {DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown },
2141 {DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },
2142
2143 {DEV_STATE_STARTWAIT_TX, DEV_EVENT_STOP, dev_action_stop },
2144 {DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXUP, dev_action_chup },
2145 {DEV_STATE_STARTWAIT_TX, DEV_EVENT_TXUP, dev_action_chup },
2146 {DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXDOWN, dev_action_chdown },
2147 {DEV_STATE_STARTWAIT_TX, DEV_EVENT_RESTART, dev_action_restart },
2148
2149 {DEV_STATE_STARTWAIT_RX, DEV_EVENT_STOP, dev_action_stop },
2150 {DEV_STATE_STARTWAIT_RX, DEV_EVENT_RXUP, dev_action_chup },
2151 {DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXUP, dev_action_chup },
2152 {DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXDOWN, dev_action_chdown },
2153 {DEV_STATE_STARTWAIT_RX, DEV_EVENT_RESTART, dev_action_restart },
2154
2155 {DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop },
2156 {DEV_STATE_RUNNING, DEV_EVENT_RXDOWN, dev_action_chdown },
2157 {DEV_STATE_RUNNING, DEV_EVENT_TXDOWN, dev_action_chdown },
2158 {DEV_STATE_RUNNING, DEV_EVENT_TXUP, fsm_action_nop },
2159 {DEV_STATE_RUNNING, DEV_EVENT_RXUP, fsm_action_nop },
2160 {DEV_STATE_RUNNING, DEV_EVENT_RESTART, dev_action_restart },
2161};
2162
2163static const int DEV_FSM_LEN = sizeof (dev_fsm) / sizeof (fsm_node);
2164
2165/**
2166 * Transmit a packet.
2167 * This is a helper function for ctc_tx().
2168 *
2169 * @param ch Channel to be used for sending.
2170 * @param skb Pointer to struct sk_buff of packet to send.
2171 * The linklevel header has already been set up
2172 * by ctc_tx().
2173 *
2174 * @return 0 on success, -ERRNO on failure. (Never fails.)
2175 */
2176static int
2177transmit_skb(struct channel *ch, struct sk_buff *skb)
2178{
2179 unsigned long saveflags;
2180 struct ll_header header;
2181 int rc = 0;
2182
2183 DBF_TEXT(trace, 5, __FUNCTION__);
2184 /* we need to acquire the lock for testing the state
2185 * otherwise we can have an IRQ changing the state to
2186 * TXIDLE after the test but before acquiring the lock.
2187 */
2188 spin_lock_irqsave(&ch->collect_lock, saveflags);
2189 if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) {
2190 int l = skb->len + LL_HEADER_LENGTH;
2191
2192 if (ch->collect_len + l > ch->max_bufsize - 2) {
2193 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
2194 return -EBUSY;
2195 } else {
2196 atomic_inc(&skb->users);
2197 header.length = l;
2198 header.type = skb->protocol;
2199 header.unused = 0;
2200 memcpy(skb_push(skb, LL_HEADER_LENGTH), &header,
2201 LL_HEADER_LENGTH);
2202 skb_queue_tail(&ch->collect_queue, skb);
2203 ch->collect_len += l;
2204 }
2205 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
2206 } else {
2207 __u16 block_len;
2208 int ccw_idx;
2209 struct sk_buff *nskb;
2210 unsigned long hi;
2211 spin_unlock_irqrestore(&ch->collect_lock, saveflags);
2212 /**
2213 * Protect skb against beeing free'd by upper
2214 * layers.
2215 */
2216 atomic_inc(&skb->users);
2217 ch->prof.txlen += skb->len;
2218 header.length = skb->len + LL_HEADER_LENGTH;
2219 header.type = skb->protocol;
2220 header.unused = 0;
2221 memcpy(skb_push(skb, LL_HEADER_LENGTH), &header,
2222 LL_HEADER_LENGTH);
2223 block_len = skb->len + 2;
2224 *((__u16 *) skb_push(skb, 2)) = block_len;
2225
2226 /**
2227 * IDAL support in CTC is broken, so we have to
2228 * care about skb's above 2G ourselves.
2229 */
2230 hi = ((unsigned long)skb_tail_pointer(skb) +
2231 LL_HEADER_LENGTH) >> 31;
2232 if (hi) {
2233 nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
2234 if (!nskb) {
2235 atomic_dec(&skb->users);
2236 skb_pull(skb, LL_HEADER_LENGTH + 2);
2237 ctc_clear_busy(ch->netdev);
2238 return -ENOMEM;
2239 } else {
2240 memcpy(skb_put(nskb, skb->len),
2241 skb->data, skb->len);
2242 atomic_inc(&nskb->users);
2243 atomic_dec(&skb->users);
2244 dev_kfree_skb_irq(skb);
2245 skb = nskb;
2246 }
2247 }
2248
2249 ch->ccw[4].count = block_len;
2250 if (set_normalized_cda(&ch->ccw[4], skb->data)) {
2251 /**
2252 * idal allocation failed, try via copying to
2253 * trans_skb. trans_skb usually has a pre-allocated
2254 * idal.
2255 */
2256 if (ctc_checkalloc_buffer(ch, 1)) {
2257 /**
2258 * Remove our header. It gets added
2259 * again on retransmit.
2260 */
2261 atomic_dec(&skb->users);
2262 skb_pull(skb, LL_HEADER_LENGTH + 2);
2263 ctc_clear_busy(ch->netdev);
2264 return -EBUSY;
2265 }
2266
2267 skb_reset_tail_pointer(ch->trans_skb);
2268 ch->trans_skb->len = 0;
2269 ch->ccw[1].count = skb->len;
2270 skb_copy_from_linear_data(skb, skb_put(ch->trans_skb,
2271 skb->len),
2272 skb->len);
2273 atomic_dec(&skb->users);
2274 dev_kfree_skb_irq(skb);
2275 ccw_idx = 0;
2276 } else {
2277 skb_queue_tail(&ch->io_queue, skb);
2278 ccw_idx = 3;
2279 }
2280 ch->retry = 0;
2281 fsm_newstate(ch->fsm, CH_STATE_TX);
2282 fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
2283 spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
2284 ch->prof.send_stamp = current_kernel_time();
2285 rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx],
2286 (unsigned long) ch, 0xff, 0);
2287 spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
2288 if (ccw_idx == 3)
2289 ch->prof.doios_single++;
2290 if (rc != 0) {
2291 fsm_deltimer(&ch->timer);
2292 ccw_check_return_code(ch, rc, "single skb TX");
2293 if (ccw_idx == 3)
2294 skb_dequeue_tail(&ch->io_queue);
2295 /**
2296 * Remove our header. It gets added
2297 * again on retransmit.
2298 */
2299 skb_pull(skb, LL_HEADER_LENGTH + 2);
2300 } else {
2301 if (ccw_idx == 0) {
2302 struct net_device *dev = ch->netdev;
2303 struct ctc_priv *privptr = dev->priv;
2304 privptr->stats.tx_packets++;
2305 privptr->stats.tx_bytes +=
2306 skb->len - LL_HEADER_LENGTH;
2307 }
2308 }
2309 }
2310
2311 ctc_clear_busy(ch->netdev);
2312 return rc;
2313}
2314
2315/**
2316 * Interface API for upper network layers
2317 *****************************************************************************/
2318
2319/**
2320 * Open an interface.
2321 * Called from generic network layer when ifconfig up is run.
2322 *
2323 * @param dev Pointer to interface struct.
2324 *
2325 * @return 0 on success, -ERRNO on failure. (Never fails.)
2326 */
2327static int
2328ctc_open(struct net_device * dev)
2329{
2330 DBF_TEXT(trace, 5, __FUNCTION__);
2331 fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_START, dev);
2332 return 0;
2333}
2334
2335/**
2336 * Close an interface.
2337 * Called from generic network layer when ifconfig down is run.
2338 *
2339 * @param dev Pointer to interface struct.
2340 *
2341 * @return 0 on success, -ERRNO on failure. (Never fails.)
2342 */
2343static int
2344ctc_close(struct net_device * dev)
2345{
2346 DBF_TEXT(trace, 5, __FUNCTION__);
2347 fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_STOP, dev);
2348 return 0;
2349}
2350
2351/**
2352 * Start transmission of a packet.
2353 * Called from generic network device layer.
2354 *
2355 * @param skb Pointer to buffer containing the packet.
2356 * @param dev Pointer to interface struct.
2357 *
2358 * @return 0 if packet consumed, !0 if packet rejected.
2359 * Note: If we return !0, then the packet is free'd by
2360 * the generic network layer.
2361 */
2362static int
2363ctc_tx(struct sk_buff *skb, struct net_device * dev)
2364{
2365 int rc = 0;
2366 struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
2367
2368 DBF_TEXT(trace, 5, __FUNCTION__);
2369 /**
2370 * Some sanity checks ...
2371 */
2372 if (skb == NULL) {
2373 ctc_pr_warn("%s: NULL sk_buff passed\n", dev->name);
2374 privptr->stats.tx_dropped++;
2375 return 0;
2376 }
2377 if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) {
2378 ctc_pr_warn("%s: Got sk_buff with head room < %ld bytes\n",
2379 dev->name, LL_HEADER_LENGTH + 2);
2380 dev_kfree_skb(skb);
2381 privptr->stats.tx_dropped++;
2382 return 0;
2383 }
2384
2385 /**
2386 * If channels are not running, try to restart them
2387 * and throw away packet.
2388 */
2389 if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
2390 fsm_event(privptr->fsm, DEV_EVENT_START, dev);
2391 dev_kfree_skb(skb);
2392 privptr->stats.tx_dropped++;
2393 privptr->stats.tx_errors++;
2394 privptr->stats.tx_carrier_errors++;
2395 return 0;
2396 }
2397
2398 if (ctc_test_and_set_busy(dev))
2399 return -EBUSY;
2400
2401 dev->trans_start = jiffies;
2402 if (transmit_skb(privptr->channel[WRITE], skb) != 0)
2403 rc = 1;
2404 return rc;
2405}
2406
2407/**
2408 * Sets MTU of an interface.
2409 *
2410 * @param dev Pointer to interface struct.
2411 * @param new_mtu The new MTU to use for this interface.
2412 *
2413 * @return 0 on success, -EINVAL if MTU is out of valid range.
2414 * (valid range is 576 .. 65527). If VM is on the
2415 * remote side, maximum MTU is 32760, however this is
2416 * <em>not</em> checked here.
2417 */
2418static int
2419ctc_change_mtu(struct net_device * dev, int new_mtu)
2420{
2421 struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
2422
2423 DBF_TEXT(trace, 3, __FUNCTION__);
2424 if ((new_mtu < 576) || (new_mtu > 65527) ||
2425 (new_mtu > (privptr->channel[READ]->max_bufsize -
2426 LL_HEADER_LENGTH - 2)))
2427 return -EINVAL;
2428 dev->mtu = new_mtu;
2429 dev->hard_header_len = LL_HEADER_LENGTH + 2;
2430 return 0;
2431}
2432
2433/**
2434 * Returns interface statistics of a device.
2435 *
2436 * @param dev Pointer to interface struct.
2437 *
2438 * @return Pointer to stats struct of this interface.
2439 */
2440static struct net_device_stats *
2441ctc_stats(struct net_device * dev)
2442{
2443 return &((struct ctc_priv *) dev->priv)->stats;
2444}
2445
2446/*
2447 * sysfs attributes
2448 */
2449
2450static ssize_t
2451buffer_show(struct device *dev, struct device_attribute *attr, char *buf)
2452{
2453 struct ctc_priv *priv;
2454
2455 priv = dev->driver_data;
2456 if (!priv)
2457 return -ENODEV;
2458 return sprintf(buf, "%d\n",
2459 priv->buffer_size);
2460}
2461
2462static ssize_t
2463buffer_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
2464{
2465 struct ctc_priv *priv;
2466 struct net_device *ndev;
2467 int bs1;
2468 char buffer[16];
2469
2470 DBF_TEXT(trace, 3, __FUNCTION__);
2471 DBF_TEXT(trace, 3, buf);
2472 priv = dev->driver_data;
2473 if (!priv) {
2474 DBF_TEXT(trace, 3, "bfnopriv");
2475 return -ENODEV;
2476 }
2477
2478 sscanf(buf, "%u", &bs1);
2479 if (bs1 > CTC_BUFSIZE_LIMIT)
2480 goto einval;
2481 if (bs1 < (576 + LL_HEADER_LENGTH + 2))
2482 goto einval;
2483 priv->buffer_size = bs1; // just to overwrite the default
2484
2485 ndev = priv->channel[READ]->netdev;
2486 if (!ndev) {
2487 DBF_TEXT(trace, 3, "bfnondev");
2488 return -ENODEV;
2489 }
2490
2491 if ((ndev->flags & IFF_RUNNING) &&
2492 (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))
2493 goto einval;
2494
2495 priv->channel[READ]->max_bufsize = bs1;
2496 priv->channel[WRITE]->max_bufsize = bs1;
2497 if (!(ndev->flags & IFF_RUNNING))
2498 ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;
2499 priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
2500 priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
2501
2502 sprintf(buffer, "%d",priv->buffer_size);
2503 DBF_TEXT(trace, 3, buffer);
2504 return count;
2505
2506einval:
2507 DBF_TEXT(trace, 3, "buff_err");
2508 return -EINVAL;
2509}
2510
2511static ssize_t
2512loglevel_show(struct device *dev, struct device_attribute *attr, char *buf)
2513{
2514 return sprintf(buf, "%d\n", loglevel);
2515}
2516
2517static ssize_t
2518loglevel_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
2519{
2520 int ll1;
2521
2522 DBF_TEXT(trace, 5, __FUNCTION__);
2523 sscanf(buf, "%i", &ll1);
2524
2525 if ((ll1 > CTC_LOGLEVEL_MAX) || (ll1 < 0))
2526 return -EINVAL;
2527 loglevel = ll1;
2528 return count;
2529}
2530
2531static void
2532ctc_print_statistics(struct ctc_priv *priv)
2533{
2534 char *sbuf;
2535 char *p;
2536
2537 DBF_TEXT(trace, 4, __FUNCTION__);
2538 if (!priv)
2539 return;
2540 sbuf = kmalloc(2048, GFP_KERNEL);
2541 if (sbuf == NULL)
2542 return;
2543 p = sbuf;
2544
2545 p += sprintf(p, " Device FSM state: %s\n",
2546 fsm_getstate_str(priv->fsm));
2547 p += sprintf(p, " RX channel FSM state: %s\n",
2548 fsm_getstate_str(priv->channel[READ]->fsm));
2549 p += sprintf(p, " TX channel FSM state: %s\n",
2550 fsm_getstate_str(priv->channel[WRITE]->fsm));
2551 p += sprintf(p, " Max. TX buffer used: %ld\n",
2552 priv->channel[WRITE]->prof.maxmulti);
2553 p += sprintf(p, " Max. chained SKBs: %ld\n",
2554 priv->channel[WRITE]->prof.maxcqueue);
2555 p += sprintf(p, " TX single write ops: %ld\n",
2556 priv->channel[WRITE]->prof.doios_single);
2557 p += sprintf(p, " TX multi write ops: %ld\n",
2558 priv->channel[WRITE]->prof.doios_multi);
2559 p += sprintf(p, " Netto bytes written: %ld\n",
2560 priv->channel[WRITE]->prof.txlen);
2561 p += sprintf(p, " Max. TX IO-time: %ld\n",
2562 priv->channel[WRITE]->prof.tx_time);
2563
2564 ctc_pr_debug("Statistics for %s:\n%s",
2565 priv->channel[WRITE]->netdev->name, sbuf);
2566 kfree(sbuf);
2567 return;
2568}
2569
2570static ssize_t
2571stats_show(struct device *dev, struct device_attribute *attr, char *buf)
2572{
2573 struct ctc_priv *priv = dev->driver_data;
2574 if (!priv)
2575 return -ENODEV;
2576 ctc_print_statistics(priv);
2577 return sprintf(buf, "0\n");
2578}
2579
2580static ssize_t
2581stats_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
2582{
2583 struct ctc_priv *priv = dev->driver_data;
2584 if (!priv)
2585 return -ENODEV;
2586 /* Reset statistics */
2587 memset(&priv->channel[WRITE]->prof, 0,
2588 sizeof(priv->channel[WRITE]->prof));
2589 return count;
2590}
2591
2592static void
2593ctc_netdev_unregister(struct net_device * dev)
2594{
2595 struct ctc_priv *privptr;
2596
2597 if (!dev)
2598 return;
2599 privptr = (struct ctc_priv *) dev->priv;
2600 unregister_netdev(dev);
2601}
2602
2603static int
2604ctc_netdev_register(struct net_device * dev)
2605{
2606 return register_netdev(dev);
2607}
2608
2609static void
2610ctc_free_netdevice(struct net_device * dev, int free_dev)
2611{
2612 struct ctc_priv *privptr;
2613 if (!dev)
2614 return;
2615 privptr = dev->priv;
2616 if (privptr) {
2617 if (privptr->fsm)
2618 kfree_fsm(privptr->fsm);
2619 kfree(privptr);
2620 }
2621#ifdef MODULE
2622 if (free_dev)
2623 free_netdev(dev);
2624#endif
2625}
2626
2627static ssize_t
2628ctc_proto_show(struct device *dev, struct device_attribute *attr, char *buf)
2629{
2630 struct ctc_priv *priv;
2631
2632 priv = dev->driver_data;
2633 if (!priv)
2634 return -ENODEV;
2635
2636 return sprintf(buf, "%d\n", priv->protocol);
2637}
2638
2639static ssize_t
2640ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
2641{
2642 struct ctc_priv *priv;
2643 int value;
2644
2645 DBF_TEXT(trace, 3, __FUNCTION__);
2646 pr_debug("%s() called\n", __FUNCTION__);
2647
2648 priv = dev->driver_data;
2649 if (!priv)
2650 return -ENODEV;
2651 sscanf(buf, "%u", &value);
2652 if (!((value == CTC_PROTO_S390) ||
2653 (value == CTC_PROTO_LINUX) ||
2654 (value == CTC_PROTO_OS390)))
2655 return -EINVAL;
2656 priv->protocol = value;
2657
2658 return count;
2659}
2660
2661static ssize_t
2662ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf)
2663{
2664 struct ccwgroup_device *cgdev;
2665
2666 cgdev = to_ccwgroupdev(dev);
2667 if (!cgdev)
2668 return -ENODEV;
2669
2670 return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]);
2671}
2672
2673static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
2674static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);
2675static DEVICE_ATTR(type, 0444, ctc_type_show, NULL);
2676
2677static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write);
2678static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
2679
2680static struct attribute *ctc_attr[] = {
2681 &dev_attr_protocol.attr,
2682 &dev_attr_type.attr,
2683 &dev_attr_buffer.attr,
2684 NULL,
2685};
2686
2687static struct attribute_group ctc_attr_group = {
2688 .attrs = ctc_attr,
2689};
2690
2691static int
2692ctc_add_attributes(struct device *dev)
2693{
2694 int rc;
2695
2696 rc = device_create_file(dev, &dev_attr_loglevel);
2697 if (rc)
2698 goto out;
2699 rc = device_create_file(dev, &dev_attr_stats);
2700 if (!rc)
2701 goto out;
2702 device_remove_file(dev, &dev_attr_loglevel);
2703out:
2704 return rc;
2705}
2706
2707static void
2708ctc_remove_attributes(struct device *dev)
2709{
2710 device_remove_file(dev, &dev_attr_stats);
2711 device_remove_file(dev, &dev_attr_loglevel);
2712}
2713
2714static int
2715ctc_add_files(struct device *dev)
2716{
2717 pr_debug("%s() called\n", __FUNCTION__);
2718
2719 return sysfs_create_group(&dev->kobj, &ctc_attr_group);
2720}
2721
2722static void
2723ctc_remove_files(struct device *dev)
2724{
2725 pr_debug("%s() called\n", __FUNCTION__);
2726
2727 sysfs_remove_group(&dev->kobj, &ctc_attr_group);
2728}
2729
2730/**
2731 * Add ctc specific attributes.
2732 * Add ctc private data.
2733 *
2734 * @param cgdev pointer to ccwgroup_device just added
2735 *
2736 * @returns 0 on success, !0 on failure.
2737 */
2738static int
2739ctc_probe_device(struct ccwgroup_device *cgdev)
2740{
2741 struct ctc_priv *priv;
2742 int rc;
2743 char buffer[16];
2744
2745 pr_debug("%s() called\n", __FUNCTION__);
2746 DBF_TEXT(setup, 3, __FUNCTION__);
2747
2748 if (!get_device(&cgdev->dev))
2749 return -ENODEV;
2750
2751 priv = kzalloc(sizeof(struct ctc_priv), GFP_KERNEL);
2752 if (!priv) {
2753 ctc_pr_err("%s: Out of memory\n", __func__);
2754 put_device(&cgdev->dev);
2755 return -ENOMEM;
2756 }
2757
2758 rc = ctc_add_files(&cgdev->dev);
2759 if (rc) {
2760 kfree(priv);
2761 put_device(&cgdev->dev);
2762 return rc;
2763 }
2764 priv->buffer_size = CTC_BUFSIZE_DEFAULT;
2765 cgdev->cdev[0]->handler = ctc_irq_handler;
2766 cgdev->cdev[1]->handler = ctc_irq_handler;
2767 cgdev->dev.driver_data = priv;
2768
2769 sprintf(buffer, "%p", priv);
2770 DBF_TEXT(data, 3, buffer);
2771
2772 sprintf(buffer, "%u", (unsigned int)sizeof(struct ctc_priv));
2773 DBF_TEXT(data, 3, buffer);
2774
2775 sprintf(buffer, "%p", &channels);
2776 DBF_TEXT(data, 3, buffer);
2777
2778 sprintf(buffer, "%u", (unsigned int)sizeof(struct channel));
2779 DBF_TEXT(data, 3, buffer);
2780
2781 return 0;
2782}
2783
2784/**
2785 * Device setup function called by alloc_netdev().
2786 *
2787 * @param dev Device to be setup.
2788 */
2789void ctc_init_netdevice(struct net_device * dev)
2790{
2791 DBF_TEXT(setup, 3, __FUNCTION__);
2792
2793 if (dev->mtu == 0)
2794 dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
2795 dev->hard_start_xmit = ctc_tx;
2796 dev->open = ctc_open;
2797 dev->stop = ctc_close;
2798 dev->get_stats = ctc_stats;
2799 dev->change_mtu = ctc_change_mtu;
2800 dev->hard_header_len = LL_HEADER_LENGTH + 2;
2801 dev->addr_len = 0;
2802 dev->type = ARPHRD_SLIP;
2803 dev->tx_queue_len = 100;
2804 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
2805}
2806
2807
2808/**
2809 *
2810 * Setup an interface.
2811 *
2812 * @param cgdev Device to be setup.
2813 *
2814 * @returns 0 on success, !0 on failure.
2815 */
2816static int
2817ctc_new_device(struct ccwgroup_device *cgdev)
2818{
2819 char read_id[CTC_ID_SIZE];
2820 char write_id[CTC_ID_SIZE];
2821 int direction;
2822 enum channel_types type;
2823 struct ctc_priv *privptr;
2824 struct net_device *dev;
2825 int ret;
2826 char buffer[16];
2827
2828 pr_debug("%s() called\n", __FUNCTION__);
2829 DBF_TEXT(setup, 3, __FUNCTION__);
2830
2831 privptr = cgdev->dev.driver_data;
2832 if (!privptr)
2833 return -ENODEV;
2834
2835 sprintf(buffer, "%d", privptr->buffer_size);
2836 DBF_TEXT(setup, 3, buffer);
2837
2838 type = get_channel_type(&cgdev->cdev[0]->id);
2839
2840 snprintf(read_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
2841 snprintf(write_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id);
2842
2843 if (add_channel(cgdev->cdev[0], type))
2844 return -ENOMEM;
2845 if (add_channel(cgdev->cdev[1], type))
2846 return -ENOMEM;
2847
2848 ret = ccw_device_set_online(cgdev->cdev[0]);
2849 if (ret != 0) {
2850 printk(KERN_WARNING
2851 "ccw_device_set_online (cdev[0]) failed with ret = %d\n", ret);
2852 }
2853
2854 ret = ccw_device_set_online(cgdev->cdev[1]);
2855 if (ret != 0) {
2856 printk(KERN_WARNING
2857 "ccw_device_set_online (cdev[1]) failed with ret = %d\n", ret);
2858 }
2859
2860 dev = alloc_netdev(0, "ctc%d", ctc_init_netdevice);
2861 if (!dev) {
2862 ctc_pr_warn("ctc_init_netdevice failed\n");
2863 goto out;
2864 }
2865 dev->priv = privptr;
2866
2867 privptr->fsm = init_fsm("ctcdev", dev_state_names,
2868 dev_event_names, CTC_NR_DEV_STATES, CTC_NR_DEV_EVENTS,
2869 dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
2870 if (privptr->fsm == NULL) {
2871 free_netdev(dev);
2872 goto out;
2873 }
2874 fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
2875 fsm_settimer(privptr->fsm, &privptr->restart_timer);
2876
2877 for (direction = READ; direction <= WRITE; direction++) {
2878 privptr->channel[direction] =
2879 channel_get(type, direction == READ ? read_id : write_id,
2880 direction);
2881 if (privptr->channel[direction] == NULL) {
2882 if (direction == WRITE)
2883 channel_free(privptr->channel[READ]);
2884
2885 ctc_free_netdevice(dev, 1);
2886 goto out;
2887 }
2888 privptr->channel[direction]->netdev = dev;
2889 privptr->channel[direction]->protocol = privptr->protocol;
2890 privptr->channel[direction]->max_bufsize = privptr->buffer_size;
2891 }
2892 /* sysfs magic */
2893 SET_NETDEV_DEV(dev, &cgdev->dev);
2894
2895 if (ctc_netdev_register(dev) != 0) {
2896 ctc_free_netdevice(dev, 1);
2897 goto out;
2898 }
2899
2900 if (ctc_add_attributes(&cgdev->dev)) {
2901 ctc_netdev_unregister(dev);
2902 dev->priv = NULL;
2903 ctc_free_netdevice(dev, 1);
2904 goto out;
2905 }
2906
2907 strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name));
2908
2909 print_banner();
2910
2911 ctc_pr_info("%s: read: %s, write: %s, proto: %d\n",
2912 dev->name, privptr->channel[READ]->id,
2913 privptr->channel[WRITE]->id, privptr->protocol);
2914
2915 return 0;
2916out:
2917 ccw_device_set_offline(cgdev->cdev[1]);
2918 ccw_device_set_offline(cgdev->cdev[0]);
2919
2920 return -ENODEV;
2921}
2922
2923/**
2924 * Shutdown an interface.
2925 *
2926 * @param cgdev Device to be shut down.
2927 *
2928 * @returns 0 on success, !0 on failure.
2929 */
2930static int
2931ctc_shutdown_device(struct ccwgroup_device *cgdev)
2932{
2933 struct ctc_priv *priv;
2934 struct net_device *ndev;
2935
2936 DBF_TEXT(setup, 3, __FUNCTION__);
2937 pr_debug("%s() called\n", __FUNCTION__);
2938
2939
2940 priv = cgdev->dev.driver_data;
2941 ndev = NULL;
2942 if (!priv)
2943 return -ENODEV;
2944
2945 if (priv->channel[READ]) {
2946 ndev = priv->channel[READ]->netdev;
2947
2948 /* Close the device */
2949 ctc_close(ndev);
2950 ndev->flags &=~IFF_RUNNING;
2951
2952 ctc_remove_attributes(&cgdev->dev);
2953
2954 channel_free(priv->channel[READ]);
2955 }
2956 if (priv->channel[WRITE])
2957 channel_free(priv->channel[WRITE]);
2958
2959 if (ndev) {
2960 ctc_netdev_unregister(ndev);
2961 ndev->priv = NULL;
2962 ctc_free_netdevice(ndev, 1);
2963 }
2964
2965 if (priv->fsm)
2966 kfree_fsm(priv->fsm);
2967
2968 ccw_device_set_offline(cgdev->cdev[1]);
2969 ccw_device_set_offline(cgdev->cdev[0]);
2970
2971 if (priv->channel[READ])
2972 channel_remove(priv->channel[READ]);
2973 if (priv->channel[WRITE])
2974 channel_remove(priv->channel[WRITE]);
2975 priv->channel[READ] = priv->channel[WRITE] = NULL;
2976
2977 return 0;
2978
2979}
2980
2981static void
2982ctc_remove_device(struct ccwgroup_device *cgdev)
2983{
2984 struct ctc_priv *priv;
2985
2986 pr_debug("%s() called\n", __FUNCTION__);
2987 DBF_TEXT(setup, 3, __FUNCTION__);
2988
2989 priv = cgdev->dev.driver_data;
2990 if (!priv)
2991 return;
2992 if (cgdev->state == CCWGROUP_ONLINE)
2993 ctc_shutdown_device(cgdev);
2994 ctc_remove_files(&cgdev->dev);
2995 cgdev->dev.driver_data = NULL;
2996 kfree(priv);
2997 put_device(&cgdev->dev);
2998}
2999
3000static struct ccwgroup_driver ctc_group_driver = {
3001 .owner = THIS_MODULE,
3002 .name = "ctc",
3003 .max_slaves = 2,
3004 .driver_id = 0xC3E3C3,
3005 .probe = ctc_probe_device,
3006 .remove = ctc_remove_device,
3007 .set_online = ctc_new_device,
3008 .set_offline = ctc_shutdown_device,
3009};
3010
3011/**
3012 * Module related routines
3013 *****************************************************************************/
3014
3015/**
3016 * Prepare to be unloaded. Free IRQ's and release all resources.
3017 * This is called just before this module is unloaded. It is
3018 * <em>not</em> called, if the usage count is !0, so we don't need to check
3019 * for that.
3020 */
3021static void __exit
3022ctc_exit(void)
3023{
3024 DBF_TEXT(setup, 3, __FUNCTION__);
3025 unregister_cu3088_discipline(&ctc_group_driver);
3026 ctc_unregister_dbf_views();
3027 ctc_pr_info("CTC driver unloaded\n");
3028}
3029
3030/**
3031 * Initialize module.
3032 * This is called just after the module is loaded.
3033 *
3034 * @return 0 on success, !0 on error.
3035 */
3036static int __init
3037ctc_init(void)
3038{
3039 int ret = 0;
3040
3041 loglevel = CTC_LOGLEVEL_DEFAULT;
3042
3043 DBF_TEXT(setup, 3, __FUNCTION__);
3044
3045 print_banner();
3046
3047 ret = ctc_register_dbf_views();
3048 if (ret){
3049 ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret);
3050 return ret;
3051 }
3052 ret = register_cu3088_discipline(&ctc_group_driver);
3053 if (ret) {
3054 ctc_unregister_dbf_views();
3055 }
3056 return ret;
3057}
3058
3059module_init(ctc_init);
3060module_exit(ctc_exit);
3061
3062/* --- This is the END my friend --- */
diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h
deleted file mode 100644
index 7f305d119f3d..000000000000
--- a/drivers/s390/net/ctcmain.h
+++ /dev/null
@@ -1,270 +0,0 @@
1/*
2 * CTC / ESCON network driver
3 *
4 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
6 Peter Tiedemann (ptiedem@de.ibm.com)
7 *
8 *
9 * Documentation used:
10 * - Principles of Operation (IBM doc#: SA22-7201-06)
11 * - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02)
12 * - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535)
13 * - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00)
14 * - ESCON I/O Interface (IBM doc#: SA22-7202-029
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
31
32#ifndef _CTCMAIN_H_
33#define _CTCMAIN_H_
34
35#include <asm/ccwdev.h>
36#include <asm/ccwgroup.h>
37
38#include <linux/skbuff.h>
39#include <linux/netdevice.h>
40
41#include "fsm.h"
42#include "cu3088.h"
43
44
45/**
46 * CCW commands, used in this driver.
47 */
48#define CCW_CMD_WRITE 0x01
49#define CCW_CMD_READ 0x02
50#define CCW_CMD_SET_EXTENDED 0xc3
51#define CCW_CMD_PREPARE 0xe3
52
53#define CTC_PROTO_S390 0
54#define CTC_PROTO_LINUX 1
55#define CTC_PROTO_OS390 3
56
57#define CTC_BUFSIZE_LIMIT 65535
58#define CTC_BUFSIZE_DEFAULT 32768
59
60#define CTC_TIMEOUT_5SEC 5000
61
62#define CTC_INITIAL_BLOCKLEN 2
63
64#define READ 0
65#define WRITE 1
66
67#define CTC_ID_SIZE BUS_ID_SIZE+3
68
69
70struct ctc_profile {
71 unsigned long maxmulti;
72 unsigned long maxcqueue;
73 unsigned long doios_single;
74 unsigned long doios_multi;
75 unsigned long txlen;
76 unsigned long tx_time;
77 struct timespec send_stamp;
78};
79
80/**
81 * Definition of one channel
82 */
83struct channel {
84
85 /**
86 * Pointer to next channel in list.
87 */
88 struct channel *next;
89 char id[CTC_ID_SIZE];
90 struct ccw_device *cdev;
91
92 /**
93 * Type of this channel.
94 * CTC/A or Escon for valid channels.
95 */
96 enum channel_types type;
97
98 /**
99 * Misc. flags. See CHANNEL_FLAGS_... below
100 */
101 __u32 flags;
102
103 /**
104 * The protocol of this channel
105 */
106 __u16 protocol;
107
108 /**
109 * I/O and irq related stuff
110 */
111 struct ccw1 *ccw;
112 struct irb *irb;
113
114 /**
115 * RX/TX buffer size
116 */
117 int max_bufsize;
118
119 /**
120 * Transmit/Receive buffer.
121 */
122 struct sk_buff *trans_skb;
123
124 /**
125 * Universal I/O queue.
126 */
127 struct sk_buff_head io_queue;
128
129 /**
130 * TX queue for collecting skb's during busy.
131 */
132 struct sk_buff_head collect_queue;
133
134 /**
135 * Amount of data in collect_queue.
136 */
137 int collect_len;
138
139 /**
140 * spinlock for collect_queue and collect_len
141 */
142 spinlock_t collect_lock;
143
144 /**
145 * Timer for detecting unresposive
146 * I/O operations.
147 */
148 fsm_timer timer;
149
150 /**
151 * Retry counter for misc. operations.
152 */
153 int retry;
154
155 /**
156 * The finite state machine of this channel
157 */
158 fsm_instance *fsm;
159
160 /**
161 * The corresponding net_device this channel
162 * belongs to.
163 */
164 struct net_device *netdev;
165
166 struct ctc_profile prof;
167
168 unsigned char *trans_skb_data;
169
170 __u16 logflags;
171};
172
173#define CHANNEL_FLAGS_READ 0
174#define CHANNEL_FLAGS_WRITE 1
175#define CHANNEL_FLAGS_INUSE 2
176#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
177#define CHANNEL_FLAGS_FAILED 8
178#define CHANNEL_FLAGS_WAITIRQ 16
179#define CHANNEL_FLAGS_RWMASK 1
180#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
181
182#define LOG_FLAG_ILLEGALPKT 1
183#define LOG_FLAG_ILLEGALSIZE 2
184#define LOG_FLAG_OVERRUN 4
185#define LOG_FLAG_NOMEM 8
186
187#define CTC_LOGLEVEL_INFO 1
188#define CTC_LOGLEVEL_NOTICE 2
189#define CTC_LOGLEVEL_WARN 4
190#define CTC_LOGLEVEL_EMERG 8
191#define CTC_LOGLEVEL_ERR 16
192#define CTC_LOGLEVEL_DEBUG 32
193#define CTC_LOGLEVEL_CRIT 64
194
195#define CTC_LOGLEVEL_DEFAULT \
196(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)
197
198#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1)
199
200#define ctc_pr_debug(fmt, arg...) \
201do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)
202
203#define ctc_pr_info(fmt, arg...) \
204do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)
205
206#define ctc_pr_notice(fmt, arg...) \
207do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)
208
209#define ctc_pr_warn(fmt, arg...) \
210do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)
211
212#define ctc_pr_emerg(fmt, arg...) \
213do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)
214
215#define ctc_pr_err(fmt, arg...) \
216do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)
217
218#define ctc_pr_crit(fmt, arg...) \
219do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)
220
221struct ctc_priv {
222 struct net_device_stats stats;
223 unsigned long tbusy;
224 /**
225 * The finite state machine of this interface.
226 */
227 fsm_instance *fsm;
228 /**
229 * The protocol of this device
230 */
231 __u16 protocol;
232 /**
233 * Timer for restarting after I/O Errors
234 */
235 fsm_timer restart_timer;
236
237 int buffer_size;
238
239 struct channel *channel[2];
240};
241
242/**
243 * Definition of our link level header.
244 */
245struct ll_header {
246 __u16 length;
247 __u16 type;
248 __u16 unused;
249};
250#define LL_HEADER_LENGTH (sizeof(struct ll_header))
251
252/**
253 * Compatibility macros for busy handling
254 * of network devices.
255 */
256static __inline__ void
257ctc_clear_busy(struct net_device * dev)
258{
259 clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
260 netif_wake_queue(dev);
261}
262
263static __inline__ int
264ctc_test_and_set_busy(struct net_device * dev)
265{
266 netif_stop_queue(dev);
267 return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
268}
269
270#endif
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth_core.h
index 8c6b72d05b1d..9485e363ca11 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth_core.h
@@ -1,40 +1,38 @@
1#ifndef __QETH_H__ 1/*
2#define __QETH_H__ 2 * drivers/s390/net/qeth_core.h
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
11#ifndef __QETH_CORE_H__
12#define __QETH_CORE_H__
3 13
4#include <linux/if.h> 14#include <linux/if.h>
5#include <linux/if_arp.h> 15#include <linux/if_arp.h>
6
7#include <linux/if_tr.h> 16#include <linux/if_tr.h>
8#include <linux/trdevice.h> 17#include <linux/trdevice.h>
9#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
10#include <linux/if_vlan.h> 19#include <linux/if_vlan.h>
11#include <linux/ctype.h> 20#include <linux/ctype.h>
21#include <linux/in6.h>
22#include <linux/bitops.h>
23#include <linux/seq_file.h>
24#include <linux/ethtool.h>
12 25
13#include <net/ipv6.h> 26#include <net/ipv6.h>
14#include <linux/in6.h>
15#include <net/if_inet6.h> 27#include <net/if_inet6.h>
16#include <net/addrconf.h> 28#include <net/addrconf.h>
17 29
18
19#include <linux/bitops.h>
20
21#include <asm/debug.h> 30#include <asm/debug.h>
22#include <asm/qdio.h> 31#include <asm/qdio.h>
23#include <asm/ccwdev.h> 32#include <asm/ccwdev.h>
24#include <asm/ccwgroup.h> 33#include <asm/ccwgroup.h>
25 34
26#include "qeth_mpc.h" 35#include "qeth_core_mpc.h"
27
28#ifdef CONFIG_QETH_IPV6
29#define QETH_VERSION_IPV6 ":IPv6"
30#else
31#define QETH_VERSION_IPV6 ""
32#endif
33#ifdef CONFIG_QETH_VLAN
34#define QETH_VERSION_VLAN ":VLAN"
35#else
36#define QETH_VERSION_VLAN ""
37#endif
38 36
39/** 37/**
40 * Debug Facility stuff 38 * Debug Facility stuff
@@ -60,15 +58,14 @@
60#define QETH_DBF_CONTROL_NAME "qeth_control" 58#define QETH_DBF_CONTROL_NAME "qeth_control"
61#define QETH_DBF_CONTROL_LEN 256 59#define QETH_DBF_CONTROL_LEN 256
62#define QETH_DBF_CONTROL_PAGES 8 60#define QETH_DBF_CONTROL_PAGES 8
63#define QETH_DBF_CONTROL_NR_AREAS 2 61#define QETH_DBF_CONTROL_NR_AREAS 1
64#define QETH_DBF_CONTROL_LEVEL 5 62#define QETH_DBF_CONTROL_LEVEL 5
65 63
66#define QETH_DBF_TRACE_NAME "qeth_trace" 64#define QETH_DBF_TRACE_NAME "qeth_trace"
67#define QETH_DBF_TRACE_LEN 8 65#define QETH_DBF_TRACE_LEN 8
68#define QETH_DBF_TRACE_PAGES 4 66#define QETH_DBF_TRACE_PAGES 4
69#define QETH_DBF_TRACE_NR_AREAS 2 67#define QETH_DBF_TRACE_NR_AREAS 1
70#define QETH_DBF_TRACE_LEVEL 3 68#define QETH_DBF_TRACE_LEVEL 3
71extern debug_info_t *qeth_dbf_trace;
72 69
73#define QETH_DBF_SENSE_NAME "qeth_sense" 70#define QETH_DBF_SENSE_NAME "qeth_sense"
74#define QETH_DBF_SENSE_LEN 64 71#define QETH_DBF_SENSE_LEN 64
@@ -79,72 +76,29 @@ extern debug_info_t *qeth_dbf_trace;
79#define QETH_DBF_QERR_NAME "qeth_qerr" 76#define QETH_DBF_QERR_NAME "qeth_qerr"
80#define QETH_DBF_QERR_LEN 8 77#define QETH_DBF_QERR_LEN 8
81#define QETH_DBF_QERR_PAGES 2 78#define QETH_DBF_QERR_PAGES 2
82#define QETH_DBF_QERR_NR_AREAS 2 79#define QETH_DBF_QERR_NR_AREAS 1
83#define QETH_DBF_QERR_LEVEL 2 80#define QETH_DBF_QERR_LEVEL 2
84 81
85#define QETH_DBF_TEXT(name,level,text) \ 82#define QETH_DBF_TEXT(name, level, text) \
86 do { \ 83 do { \
87 debug_text_event(qeth_dbf_##name,level,text); \ 84 debug_text_event(qeth_dbf_##name, level, text); \
88 } while (0) 85 } while (0)
89 86
90#define QETH_DBF_HEX(name,level,addr,len) \ 87#define QETH_DBF_HEX(name, level, addr, len) \
91 do { \ 88 do { \
92 debug_event(qeth_dbf_##name,level,(void*)(addr),len); \ 89 debug_event(qeth_dbf_##name, level, (void *)(addr), len); \
93 } while (0)
94
95DECLARE_PER_CPU(char[256], qeth_dbf_txt_buf);
96
97#define QETH_DBF_TEXT_(name,level,text...) \
98 do { \
99 char* dbf_txt_buf = get_cpu_var(qeth_dbf_txt_buf); \
100 sprintf(dbf_txt_buf, text); \
101 debug_text_event(qeth_dbf_##name,level,dbf_txt_buf); \
102 put_cpu_var(qeth_dbf_txt_buf); \
103 } while (0) 90 } while (0)
104 91
105#define QETH_DBF_SPRINTF(name,level,text...) \ 92/* Allow to sort out low debug levels early to avoid wasted sprints */
106 do { \ 93static inline int qeth_dbf_passes(debug_info_t *dbf_grp, int level)
107 debug_sprintf_event(qeth_dbf_trace, level, ##text ); \ 94{
108 debug_sprintf_event(qeth_dbf_trace, level, text ); \ 95 return (level <= dbf_grp->level);
109 } while (0) 96}
110 97
111/** 98/**
112 * some more debug stuff 99 * some more debug stuff
113 */ 100 */
114#define PRINTK_HEADER "qeth: " 101#define PRINTK_HEADER "qeth: "
115
116#define HEXDUMP16(importance,header,ptr) \
117PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
118 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
119 *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
120 *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
121 *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
122 *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
123 *(((char*)ptr)+12),*(((char*)ptr)+13), \
124 *(((char*)ptr)+14),*(((char*)ptr)+15)); \
125PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
126 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
127 *(((char*)ptr)+16),*(((char*)ptr)+17), \
128 *(((char*)ptr)+18),*(((char*)ptr)+19), \
129 *(((char*)ptr)+20),*(((char*)ptr)+21), \
130 *(((char*)ptr)+22),*(((char*)ptr)+23), \
131 *(((char*)ptr)+24),*(((char*)ptr)+25), \
132 *(((char*)ptr)+26),*(((char*)ptr)+27), \
133 *(((char*)ptr)+28),*(((char*)ptr)+29), \
134 *(((char*)ptr)+30),*(((char*)ptr)+31));
135
136static inline void
137qeth_hex_dump(unsigned char *buf, size_t len)
138{
139 size_t i;
140
141 for (i = 0; i < len; i++) {
142 if (i && !(i % 16))
143 printk("\n");
144 printk("%02x ", *(buf + i));
145 }
146 printk("\n");
147}
148 102
149#define SENSE_COMMAND_REJECT_BYTE 0 103#define SENSE_COMMAND_REJECT_BYTE 0
150#define SENSE_COMMAND_REJECT_FLAG 0x80 104#define SENSE_COMMAND_REJECT_FLAG 0x80
@@ -154,10 +108,6 @@ qeth_hex_dump(unsigned char *buf, size_t len)
154/* 108/*
155 * Common IO related definitions 109 * Common IO related definitions
156 */ 110 */
157extern struct device *qeth_root_dev;
158extern struct ccw_driver qeth_ccw_driver;
159extern struct ccwgroup_driver qeth_ccwgroup_driver;
160
161#define CARD_RDEV(card) card->read.ccwdev 111#define CARD_RDEV(card) card->read.ccwdev
162#define CARD_WDEV(card) card->write.ccwdev 112#define CARD_WDEV(card) card->write.ccwdev
163#define CARD_DDEV(card) card->data.ccwdev 113#define CARD_DDEV(card) card->data.ccwdev
@@ -167,10 +117,6 @@ extern struct ccwgroup_driver qeth_ccwgroup_driver;
167#define CARD_DDEV_ID(card) card->data.ccwdev->dev.bus_id 117#define CARD_DDEV_ID(card) card->data.ccwdev->dev.bus_id
168#define CHANNEL_ID(channel) channel->ccwdev->dev.bus_id 118#define CHANNEL_ID(channel) channel->ccwdev->dev.bus_id
169 119
170#define CARD_FROM_CDEV(cdev) (struct qeth_card *) \
171 ((struct ccwgroup_device *)cdev->dev.driver_data)\
172 ->dev.driver_data;
173
174/** 120/**
175 * card stuff 121 * card stuff
176 */ 122 */
@@ -228,40 +174,36 @@ struct qeth_ipa_info {
228 __u32 enabled_funcs; 174 __u32 enabled_funcs;
229}; 175};
230 176
231static inline int 177static inline int qeth_is_ipa_supported(struct qeth_ipa_info *ipa,
232qeth_is_ipa_supported(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) 178 enum qeth_ipa_funcs func)
233{ 179{
234 return (ipa->supported_funcs & func); 180 return (ipa->supported_funcs & func);
235} 181}
236 182
237static inline int 183static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
238qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) 184 enum qeth_ipa_funcs func)
239{ 185{
240 return (ipa->supported_funcs & ipa->enabled_funcs & func); 186 return (ipa->supported_funcs & ipa->enabled_funcs & func);
241} 187}
242 188
243#define qeth_adp_supported(c,f) \ 189#define qeth_adp_supported(c, f) \
244 qeth_is_ipa_supported(&c->options.adp, f) 190 qeth_is_ipa_supported(&c->options.adp, f)
245#define qeth_adp_enabled(c,f) \ 191#define qeth_adp_enabled(c, f) \
246 qeth_is_ipa_enabled(&c->options.adp, f) 192 qeth_is_ipa_enabled(&c->options.adp, f)
247#define qeth_is_supported(c,f) \ 193#define qeth_is_supported(c, f) \
248 qeth_is_ipa_supported(&c->options.ipa4, f) 194 qeth_is_ipa_supported(&c->options.ipa4, f)
249#define qeth_is_enabled(c,f) \ 195#define qeth_is_enabled(c, f) \
250 qeth_is_ipa_enabled(&c->options.ipa4, f) 196 qeth_is_ipa_enabled(&c->options.ipa4, f)
251#ifdef CONFIG_QETH_IPV6 197#define qeth_is_supported6(c, f) \
252#define qeth_is_supported6(c,f) \
253 qeth_is_ipa_supported(&c->options.ipa6, f) 198 qeth_is_ipa_supported(&c->options.ipa6, f)
254#define qeth_is_enabled6(c,f) \ 199#define qeth_is_enabled6(c, f) \
255 qeth_is_ipa_enabled(&c->options.ipa6, f) 200 qeth_is_ipa_enabled(&c->options.ipa6, f)
256#else /* CONFIG_QETH_IPV6 */ 201#define qeth_is_ipafunc_supported(c, prot, f) \
257#define qeth_is_supported6(c,f) 0 202 ((prot == QETH_PROT_IPV6) ? \
258#define qeth_is_enabled6(c,f) 0 203 qeth_is_supported6(c, f) : qeth_is_supported(c, f))
259#endif /* CONFIG_QETH_IPV6 */ 204#define qeth_is_ipafunc_enabled(c, prot, f) \
260#define qeth_is_ipafunc_supported(c,prot,f) \ 205 ((prot == QETH_PROT_IPV6) ? \
261 (prot==QETH_PROT_IPV6)? qeth_is_supported6(c,f):qeth_is_supported(c,f) 206 qeth_is_enabled6(c, f) : qeth_is_enabled(c, f))
262#define qeth_is_ipafunc_enabled(c,prot,f) \
263 (prot==QETH_PROT_IPV6)? qeth_is_enabled6(c,f):qeth_is_enabled(c,f)
264
265 207
266#define QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT 0x0101 208#define QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT 0x0101
267#define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x0101 209#define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x0101
@@ -269,39 +211,35 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
269#define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 211#define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108
270 212
271#define QETH_MODELLIST_ARRAY \ 213#define QETH_MODELLIST_ARRAY \
272 {{0x1731,0x01,0x1732,0x01,QETH_CARD_TYPE_OSAE,1, \ 214 {{0x1731, 0x01, 0x1732, 0x01, QETH_CARD_TYPE_OSAE, 1, \
273 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \ 215 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
274 QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \ 216 QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
275 QETH_MAX_QUEUES,0}, \ 217 QETH_MAX_QUEUES, 0}, \
276 {0x1731,0x05,0x1732,0x05,QETH_CARD_TYPE_IQD,0, \ 218 {0x1731, 0x05, 0x1732, 0x05, QETH_CARD_TYPE_IQD, 0, \
277 QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \ 219 QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \
278 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \ 220 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \
279 QETH_MAX_QUEUES,0x103}, \ 221 QETH_MAX_QUEUES, 0x103}, \
280 {0x1731,0x06,0x1732,0x06,QETH_CARD_TYPE_OSN,0, \ 222 {0x1731, 0x06, 0x1732, 0x06, QETH_CARD_TYPE_OSN, 0, \
281 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \ 223 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
282 QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \ 224 QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
283 QETH_MAX_QUEUES,0}, \ 225 QETH_MAX_QUEUES, 0}, \
284 {0,0,0,0,0,0,0,0,0}} 226 {0, 0, 0, 0, 0, 0, 0, 0, 0} }
285 227
286#define QETH_REAL_CARD 1 228#define QETH_REAL_CARD 1
287#define QETH_VLAN_CARD 2 229#define QETH_VLAN_CARD 2
288#define QETH_BUFSIZE 4096 230#define QETH_BUFSIZE 4096
289 231
290/** 232/**
291 * some more defs 233 * some more defs
292 */ 234 */
293#define IF_NAME_LEN 16
294#define QETH_TX_TIMEOUT 100 * HZ 235#define QETH_TX_TIMEOUT 100 * HZ
295#define QETH_RCD_TIMEOUT 60 * HZ 236#define QETH_RCD_TIMEOUT 60 * HZ
296#define QETH_HEADER_SIZE 32 237#define QETH_HEADER_SIZE 32
297#define MAX_PORTNO 15 238#define QETH_MAX_PORTNO 15
298#define QETH_FAKE_LL_LEN_ETH ETH_HLEN
299#define QETH_FAKE_LL_LEN_TR (sizeof(struct trh_hdr)-TR_MAXRIFLEN+sizeof(struct trllc))
300#define QETH_FAKE_LL_V6_ADDR_POS 24
301 239
302/*IPv6 address autoconfiguration stuff*/ 240/*IPv6 address autoconfiguration stuff*/
303#define UNIQUE_ID_IF_CREATE_ADDR_FAILED 0xfffe 241#define UNIQUE_ID_IF_CREATE_ADDR_FAILED 0xfffe
304#define UNIQUE_ID_NOT_BY_CARD 0x10000 242#define UNIQUE_ID_NOT_BY_CARD 0x10000
305 243
306/*****************************************************************************/ 244/*****************************************************************************/
307/* QDIO queue and buffer handling */ 245/* QDIO queue and buffer handling */
@@ -394,20 +332,20 @@ struct qeth_hdr {
394 332
395/*TCP Segmentation Offload header*/ 333/*TCP Segmentation Offload header*/
396struct qeth_hdr_ext_tso { 334struct qeth_hdr_ext_tso {
397 __u16 hdr_tot_len; 335 __u16 hdr_tot_len;
398 __u8 imb_hdr_no; 336 __u8 imb_hdr_no;
399 __u8 reserved; 337 __u8 reserved;
400 __u8 hdr_type; 338 __u8 hdr_type;
401 __u8 hdr_version; 339 __u8 hdr_version;
402 __u16 hdr_len; 340 __u16 hdr_len;
403 __u32 payload_len; 341 __u32 payload_len;
404 __u16 mss; 342 __u16 mss;
405 __u16 dg_hdr_len; 343 __u16 dg_hdr_len;
406 __u8 padding[16]; 344 __u8 padding[16];
407} __attribute__ ((packed)); 345} __attribute__ ((packed));
408 346
409struct qeth_hdr_tso { 347struct qeth_hdr_tso {
410 struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/ 348 struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/
411 struct qeth_hdr_ext_tso ext; 349 struct qeth_hdr_ext_tso ext;
412} __attribute__ ((packed)); 350} __attribute__ ((packed));
413 351
@@ -446,8 +384,7 @@ enum qeth_header_ids {
446#define QETH_HDR_EXT_CSUM_TRANSP_REQ 0x20 384#define QETH_HDR_EXT_CSUM_TRANSP_REQ 0x20
447#define QETH_HDR_EXT_UDP_TSO 0x40 /*bit off for TCP*/ 385#define QETH_HDR_EXT_UDP_TSO 0x40 /*bit off for TCP*/
448 386
449static inline int 387static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale)
450qeth_is_last_sbale(struct qdio_buffer_element *sbale)
451{ 388{
452 return (sbale->flags & SBAL_FLAGS_LAST_ENTRY); 389 return (sbale->flags & SBAL_FLAGS_LAST_ENTRY);
453} 390}
@@ -485,7 +422,6 @@ struct qeth_qdio_buffer_pool {
485 422
486struct qeth_qdio_buffer { 423struct qeth_qdio_buffer {
487 struct qdio_buffer *buffer; 424 struct qdio_buffer *buffer;
488 volatile enum qeth_qdio_buffer_states state;
489 /* the buffer pool entry currently associated to this buffer */ 425 /* the buffer pool entry currently associated to this buffer */
490 struct qeth_buffer_pool_entry *pool_entry; 426 struct qeth_buffer_pool_entry *pool_entry;
491}; 427};
@@ -493,11 +429,7 @@ struct qeth_qdio_buffer {
493struct qeth_qdio_q { 429struct qeth_qdio_q {
494 struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; 430 struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
495 struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q]; 431 struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q];
496 /* 432 int next_buf_to_init;
497 * buf_to_init means "buffer must be initialized by driver and must
498 * be made available for hardware" -> state is set to EMPTY
499 */
500 volatile int next_buf_to_init;
501} __attribute__ ((aligned(256))); 433} __attribute__ ((aligned(256)));
502 434
503/* possible types of qeth large_send support */ 435/* possible types of qeth large_send support */
@@ -510,7 +442,7 @@ enum qeth_large_send_types {
510struct qeth_qdio_out_buffer { 442struct qeth_qdio_out_buffer {
511 struct qdio_buffer *buffer; 443 struct qdio_buffer *buffer;
512 atomic_t state; 444 atomic_t state;
513 volatile int next_element_to_fill; 445 int next_element_to_fill;
514 struct sk_buff_head skb_list; 446 struct sk_buff_head skb_list;
515 struct list_head ctx_list; 447 struct list_head ctx_list;
516}; 448};
@@ -529,11 +461,11 @@ struct qeth_qdio_out_q {
529 int queue_no; 461 int queue_no;
530 struct qeth_card *card; 462 struct qeth_card *card;
531 atomic_t state; 463 atomic_t state;
532 volatile int do_pack; 464 int do_pack;
533 /* 465 /*
534 * index of buffer to be filled by driver; state EMPTY or PACKING 466 * index of buffer to be filled by driver; state EMPTY or PACKING
535 */ 467 */
536 volatile int next_buf_to_fill; 468 int next_buf_to_fill;
537 /* 469 /*
538 * number of buffers that are currently filled (PRIMED) 470 * number of buffers that are currently filled (PRIMED)
539 * -> these buffers are hardware-owned 471 * -> these buffers are hardware-owned
@@ -624,36 +556,6 @@ enum qeth_cmd_buffer_state {
624 BUF_STATE_LOCKED, 556 BUF_STATE_LOCKED,
625 BUF_STATE_PROCESSED, 557 BUF_STATE_PROCESSED,
626}; 558};
627/**
628 * IP address and multicast list
629 */
630struct qeth_ipaddr {
631 struct list_head entry;
632 enum qeth_ip_types type;
633 enum qeth_ipa_setdelip_flags set_flags;
634 enum qeth_ipa_setdelip_flags del_flags;
635 int is_multicast;
636 volatile int users;
637 enum qeth_prot_versions proto;
638 unsigned char mac[OSA_ADDR_LEN];
639 union {
640 struct {
641 unsigned int addr;
642 unsigned int mask;
643 } a4;
644 struct {
645 struct in6_addr addr;
646 unsigned int pfxlen;
647 } a6;
648 } u;
649};
650
651struct qeth_ipato_entry {
652 struct list_head entry;
653 enum qeth_prot_versions proto;
654 char addr[16];
655 int mask_bits;
656};
657 559
658struct qeth_ipato { 560struct qeth_ipato {
659 int enabled; 561 int enabled;
@@ -672,7 +574,6 @@ struct qeth_cmd_buffer {
672 void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *); 574 void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *);
673}; 575};
674 576
675
676/** 577/**
677 * definition of a qeth channel, used for read and write 578 * definition of a qeth channel, used for read and write
678 */ 579 */
@@ -686,8 +587,8 @@ struct qeth_channel {
686/*command buffer for control data*/ 587/*command buffer for control data*/
687 struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO]; 588 struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO];
688 atomic_t irq_pending; 589 atomic_t irq_pending;
689 volatile int io_buf_no; 590 int io_buf_no;
690 volatile int buf_no; 591 int buf_no;
691}; 592};
692 593
693/** 594/**
@@ -717,8 +618,9 @@ struct qeth_seqno {
717struct qeth_reply { 618struct qeth_reply {
718 struct list_head list; 619 struct list_head list;
719 wait_queue_head_t wait_q; 620 wait_queue_head_t wait_q;
720 int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long); 621 int (*callback)(struct qeth_card *, struct qeth_reply *,
721 u32 seqno; 622 unsigned long);
623 u32 seqno;
722 unsigned long offset; 624 unsigned long offset;
723 atomic_t received; 625 atomic_t received;
724 int rc; 626 int rc;
@@ -765,10 +667,8 @@ struct qeth_card_options {
765 struct qeth_routing_info route4; 667 struct qeth_routing_info route4;
766 struct qeth_ipa_info ipa4; 668 struct qeth_ipa_info ipa4;
767 struct qeth_ipa_info adp; /*Adapter parameters*/ 669 struct qeth_ipa_info adp; /*Adapter parameters*/
768#ifdef CONFIG_QETH_IPV6
769 struct qeth_routing_info route6; 670 struct qeth_routing_info route6;
770 struct qeth_ipa_info ipa6; 671 struct qeth_ipa_info ipa6;
771#endif /* QETH_IPV6 */
772 enum qeth_checksum_types checksum_type; 672 enum qeth_checksum_types checksum_type;
773 int broadcast_mode; 673 int broadcast_mode;
774 int macaddr_mode; 674 int macaddr_mode;
@@ -785,9 +685,7 @@ struct qeth_card_options {
785 * thread bits for qeth_card thread masks 685 * thread bits for qeth_card thread masks
786 */ 686 */
787enum qeth_threads { 687enum qeth_threads {
788 QETH_SET_IP_THREAD = 1, 688 QETH_RECOVER_THREAD = 1,
789 QETH_RECOVER_THREAD = 2,
790 QETH_SET_PROMISC_MODE_THREAD = 4,
791}; 689};
792 690
793struct qeth_osn_info { 691struct qeth_osn_info {
@@ -795,12 +693,34 @@ struct qeth_osn_info {
795 int (*data_cb)(struct sk_buff *skb); 693 int (*data_cb)(struct sk_buff *skb);
796}; 694};
797 695
696enum qeth_discipline_id {
697 QETH_DISCIPLINE_LAYER3 = 0,
698 QETH_DISCIPLINE_LAYER2 = 1,
699};
700
701struct qeth_discipline {
702 qdio_handler_t *input_handler;
703 qdio_handler_t *output_handler;
704 int (*recover)(void *ptr);
705 struct ccwgroup_driver *ccwgdriver;
706};
707
708struct qeth_vlan_vid {
709 struct list_head list;
710 unsigned short vid;
711};
712
713struct qeth_mc_mac {
714 struct list_head list;
715 __u8 mc_addr[MAX_ADDR_LEN];
716 unsigned char mc_addrlen;
717};
718
798struct qeth_card { 719struct qeth_card {
799 struct list_head list; 720 struct list_head list;
800 enum qeth_card_states state; 721 enum qeth_card_states state;
801 int lan_online; 722 int lan_online;
802 spinlock_t lock; 723 spinlock_t lock;
803/*hardware and sysfs stuff*/
804 struct ccwgroup_device *gdev; 724 struct ccwgroup_device *gdev;
805 struct qeth_channel read; 725 struct qeth_channel read;
806 struct qeth_channel write; 726 struct qeth_channel write;
@@ -815,15 +735,16 @@ struct qeth_card {
815 struct qeth_card_options options; 735 struct qeth_card_options options;
816 736
817 wait_queue_head_t wait_q; 737 wait_queue_head_t wait_q;
818#ifdef CONFIG_QETH_VLAN
819 spinlock_t vlanlock; 738 spinlock_t vlanlock;
739 spinlock_t mclock;
820 struct vlan_group *vlangrp; 740 struct vlan_group *vlangrp;
821#endif 741 struct list_head vid_list;
742 struct list_head mc_list;
822 struct work_struct kernel_thread_starter; 743 struct work_struct kernel_thread_starter;
823 spinlock_t thread_mask_lock; 744 spinlock_t thread_mask_lock;
824 volatile unsigned long thread_start_mask; 745 unsigned long thread_start_mask;
825 volatile unsigned long thread_allowed_mask; 746 unsigned long thread_allowed_mask;
826 volatile unsigned long thread_running_mask; 747 unsigned long thread_running_mask;
827 spinlock_t ip_lock; 748 spinlock_t ip_lock;
828 struct list_head ip_list; 749 struct list_head ip_list;
829 struct list_head *ip_tbd_list; 750 struct list_head *ip_tbd_list;
@@ -833,8 +754,8 @@ struct qeth_card {
833 struct qeth_qdio_info qdio; 754 struct qeth_qdio_info qdio;
834 struct qeth_perf_stats perf_stats; 755 struct qeth_perf_stats perf_stats;
835 int use_hard_stop; 756 int use_hard_stop;
836 const struct header_ops *orig_header_ops;
837 struct qeth_osn_info osn_info; 757 struct qeth_osn_info osn_info;
758 struct qeth_discipline discipline;
838 atomic_t force_alloc_skb; 759 atomic_t force_alloc_skb;
839}; 760};
840 761
@@ -843,411 +764,153 @@ struct qeth_card_list_struct {
843 rwlock_t rwlock; 764 rwlock_t rwlock;
844}; 765};
845 766
846extern struct qeth_card_list_struct qeth_card_list;
847
848/*notifier list */
849struct qeth_notify_list_struct {
850 struct list_head list;
851 struct task_struct *task;
852 int signum;
853};
854extern spinlock_t qeth_notify_lock;
855extern struct list_head qeth_notify_list;
856
857/*some helper functions*/ 767/*some helper functions*/
858
859#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "") 768#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
860 769
861static inline __u8 770static inline struct qeth_card *CARD_FROM_CDEV(struct ccw_device *cdev)
862qeth_get_ipa_adp_type(enum qeth_link_types link_type)
863{ 771{
864 switch (link_type) { 772 struct qeth_card *card = dev_get_drvdata(&((struct ccwgroup_device *)
865 case QETH_LINK_TYPE_HSTR: 773 dev_get_drvdata(&cdev->dev))->dev);
866 return 2; 774 return card;
867 default:
868 return 1;
869 }
870} 775}
871 776
872static inline struct sk_buff * 777static inline int qeth_get_micros(void)
873qeth_realloc_headroom(struct qeth_card *card, struct sk_buff *skb, int size)
874{ 778{
875 struct sk_buff *new_skb = skb; 779 return (int) (get_clock() >> 12);
876
877 if (skb_headroom(skb) >= size)
878 return skb;
879 new_skb = skb_realloc_headroom(skb, size);
880 if (!new_skb)
881 PRINT_ERR("Could not realloc headroom for qeth_hdr "
882 "on interface %s", QETH_CARD_IFNAME(card));
883 return new_skb;
884}
885
886static inline struct sk_buff *
887qeth_pskb_unshare(struct sk_buff *skb, gfp_t pri)
888{
889 struct sk_buff *nskb;
890 if (!skb_cloned(skb))
891 return skb;
892 nskb = skb_copy(skb, pri);
893 return nskb;
894} 780}
895 781
896static inline void * 782static inline void *qeth_push_skb(struct qeth_card *card, struct sk_buff *skb,
897qeth_push_skb(struct qeth_card *card, struct sk_buff *skb, int size) 783 int size)
898{ 784{
899 void *hdr; 785 void *hdr;
900 786
901 hdr = (void *) skb_push(skb, size); 787 hdr = (void *) skb_push(skb, size);
902 /* 788 /*
903 * sanity check, the Linux memory allocation scheme should 789 * sanity check, the Linux memory allocation scheme should
904 * never present us cases like this one (the qdio header size plus 790 * never present us cases like this one (the qdio header size plus
905 * the first 40 bytes of the paket cross a 4k boundary) 791 * the first 40 bytes of the paket cross a 4k boundary)
906 */ 792 */
907 if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) != 793 if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) !=
908 (((unsigned long) hdr + size + 794 (((unsigned long) hdr + size +
909 QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) { 795 QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) {
910 PRINT_ERR("Misaligned packet on interface %s. Discarded.", 796 PRINT_ERR("Misaligned packet on interface %s. Discarded.",
911 QETH_CARD_IFNAME(card)); 797 QETH_CARD_IFNAME(card));
912 return NULL; 798 return NULL;
913 }
914 return hdr;
915}
916
917
918static inline int
919qeth_get_hlen(__u8 link_type)
920{
921#ifdef CONFIG_QETH_IPV6
922 switch (link_type) {
923 case QETH_LINK_TYPE_HSTR:
924 case QETH_LINK_TYPE_LANE_TR:
925 return sizeof(struct qeth_hdr_tso) + TR_HLEN;
926 default:
927#ifdef CONFIG_QETH_VLAN
928 return sizeof(struct qeth_hdr_tso) + VLAN_ETH_HLEN;
929#else
930 return sizeof(struct qeth_hdr_tso) + ETH_HLEN;
931#endif
932 }
933#else /* CONFIG_QETH_IPV6 */
934#ifdef CONFIG_QETH_VLAN
935 return sizeof(struct qeth_hdr_tso) + VLAN_HLEN;
936#else
937 return sizeof(struct qeth_hdr_tso);
938#endif
939#endif /* CONFIG_QETH_IPV6 */
940}
941
942static inline unsigned short
943qeth_get_netdev_flags(struct qeth_card *card)
944{
945 if (card->options.layer2 &&
946 (card->info.type == QETH_CARD_TYPE_OSAE))
947 return 0;
948 switch (card->info.type) {
949 case QETH_CARD_TYPE_IQD:
950 case QETH_CARD_TYPE_OSN:
951 return IFF_NOARP;
952#ifdef CONFIG_QETH_IPV6
953 default:
954 return 0;
955#else
956 default:
957 return IFF_NOARP;
958#endif
959 }
960}
961
962static inline int
963qeth_get_initial_mtu_for_card(struct qeth_card * card)
964{
965 switch (card->info.type) {
966 case QETH_CARD_TYPE_UNKNOWN:
967 return 1500;
968 case QETH_CARD_TYPE_IQD:
969 return card->info.max_mtu;
970 case QETH_CARD_TYPE_OSAE:
971 switch (card->info.link_type) {
972 case QETH_LINK_TYPE_HSTR:
973 case QETH_LINK_TYPE_LANE_TR:
974 return 2000;
975 default:
976 return 1492;
977 }
978 default:
979 return 1500;
980 }
981}
982
983static inline int
984qeth_get_max_mtu_for_card(int cardtype)
985{
986 switch (cardtype) {
987
988 case QETH_CARD_TYPE_UNKNOWN:
989 case QETH_CARD_TYPE_OSAE:
990 case QETH_CARD_TYPE_OSN:
991 return 61440;
992 case QETH_CARD_TYPE_IQD:
993 return 57344;
994 default:
995 return 1500;
996 }
997}
998
999static inline int
1000qeth_get_mtu_out_of_mpc(int cardtype)
1001{
1002 switch (cardtype) {
1003 case QETH_CARD_TYPE_IQD:
1004 return 1;
1005 default:
1006 return 0;
1007 }
1008}
1009
1010static inline int
1011qeth_get_mtu_outof_framesize(int framesize)
1012{
1013 switch (framesize) {
1014 case 0x4000:
1015 return 8192;
1016 case 0x6000:
1017 return 16384;
1018 case 0xa000:
1019 return 32768;
1020 case 0xffff:
1021 return 57344;
1022 default:
1023 return 0;
1024 }
1025}
1026
1027static inline int
1028qeth_mtu_is_valid(struct qeth_card * card, int mtu)
1029{
1030 switch (card->info.type) {
1031 case QETH_CARD_TYPE_OSAE:
1032 return ((mtu >= 576) && (mtu <= 61440));
1033 case QETH_CARD_TYPE_IQD:
1034 return ((mtu >= 576) &&
1035 (mtu <= card->info.max_mtu + 4096 - 32));
1036 case QETH_CARD_TYPE_OSN:
1037 case QETH_CARD_TYPE_UNKNOWN:
1038 default:
1039 return 1;
1040 }
1041}
1042
1043static inline int
1044qeth_get_arphdr_type(int cardtype, int linktype)
1045{
1046 switch (cardtype) {
1047 case QETH_CARD_TYPE_OSAE:
1048 case QETH_CARD_TYPE_OSN:
1049 switch (linktype) {
1050 case QETH_LINK_TYPE_LANE_TR:
1051 case QETH_LINK_TYPE_HSTR:
1052 return ARPHRD_IEEE802_TR;
1053 default:
1054 return ARPHRD_ETHER;
1055 }
1056 case QETH_CARD_TYPE_IQD:
1057 default:
1058 return ARPHRD_ETHER;
1059 } 799 }
800 return hdr;
1060} 801}
1061 802
1062static inline int 803static inline int qeth_get_ip_version(struct sk_buff *skb)
1063qeth_get_micros(void)
1064{
1065 return (int) (get_clock() >> 12);
1066}
1067
1068static inline int
1069qeth_get_qdio_q_format(struct qeth_card *card)
1070{ 804{
1071 switch (card->info.type) { 805 switch (skb->protocol) {
1072 case QETH_CARD_TYPE_IQD: 806 case ETH_P_IPV6:
1073 return 2; 807 return 6;
808 case ETH_P_IP:
809 return 4;
1074 default: 810 default:
1075 return 0; 811 return 0;
1076 } 812 }
1077} 813}
1078 814
1079static inline int 815struct qeth_eddp_context;
1080qeth_isxdigit(char * buf) 816extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
1081{ 817extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
1082 while (*buf) { 818const char *qeth_get_cardname_short(struct qeth_card *);
1083 if (!isxdigit(*buf++)) 819int qeth_realloc_buffer_pool(struct qeth_card *, int);
1084 return 0; 820int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id);
1085 } 821void qeth_core_free_discipline(struct qeth_card *);
1086 return 1; 822int qeth_core_create_device_attributes(struct device *);
1087} 823void qeth_core_remove_device_attributes(struct device *);
1088 824int qeth_core_create_osn_attributes(struct device *);
1089static inline void 825void qeth_core_remove_osn_attributes(struct device *);
1090qeth_ipaddr4_to_string(const __u8 *addr, char *buf) 826
1091{ 827/* exports for qeth discipline device drivers */
1092 sprintf(buf, "%i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]); 828extern struct qeth_card_list_struct qeth_core_card_list;
1093} 829extern debug_info_t *qeth_dbf_setup;
1094 830extern debug_info_t *qeth_dbf_data;
1095static inline int 831extern debug_info_t *qeth_dbf_misc;
1096qeth_string_to_ipaddr4(const char *buf, __u8 *addr) 832extern debug_info_t *qeth_dbf_control;
1097{ 833extern debug_info_t *qeth_dbf_trace;
1098 int count = 0, rc = 0; 834extern debug_info_t *qeth_dbf_sense;
1099 int in[4]; 835extern debug_info_t *qeth_dbf_qerr;
1100 char c; 836
1101 837void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
1102 rc = sscanf(buf, "%u.%u.%u.%u%c", 838int qeth_threads_running(struct qeth_card *, unsigned long);
1103 &in[0], &in[1], &in[2], &in[3], &c); 839int qeth_wait_for_threads(struct qeth_card *, unsigned long);
1104 if (rc != 4 && (rc != 5 || c != '\n')) 840int qeth_do_run_thread(struct qeth_card *, unsigned long);
1105 return -EINVAL; 841void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long);
1106 for (count = 0; count < 4; count++) { 842void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
1107 if (in[count] > 255) 843int qeth_core_hardsetup_card(struct qeth_card *);
1108 return -EINVAL; 844void qeth_print_status_message(struct qeth_card *);
1109 addr[count] = in[count]; 845int qeth_init_qdio_queues(struct qeth_card *);
1110 } 846int qeth_send_startlan(struct qeth_card *);
1111 return 0; 847int qeth_send_stoplan(struct qeth_card *);
1112} 848int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
1113 849 int (*reply_cb)
1114static inline void 850 (struct qeth_card *, struct qeth_reply *, unsigned long),
1115qeth_ipaddr6_to_string(const __u8 *addr, char *buf) 851 void *);
1116{ 852struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
1117 sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x" 853 enum qeth_ipa_cmds, enum qeth_prot_versions);
1118 ":%02x%02x:%02x%02x:%02x%02x:%02x%02x", 854int qeth_query_setadapterparms(struct qeth_card *);
1119 addr[0], addr[1], addr[2], addr[3], 855int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int,
1120 addr[4], addr[5], addr[6], addr[7], 856 unsigned int, const char *);
1121 addr[8], addr[9], addr[10], addr[11], 857void qeth_put_buffer_pool_entry(struct qeth_card *,
1122 addr[12], addr[13], addr[14], addr[15]); 858 struct qeth_buffer_pool_entry *);
1123} 859void qeth_queue_input_buffer(struct qeth_card *, int);
1124 860struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
1125static inline int 861 struct qdio_buffer *, struct qdio_buffer_element **, int *,
1126qeth_string_to_ipaddr6(const char *buf, __u8 *addr) 862 struct qeth_hdr **);
1127{ 863void qeth_schedule_recovery(struct qeth_card *);
1128 const char *end, *end_tmp, *start; 864void qeth_qdio_output_handler(struct ccw_device *, unsigned int,
1129 __u16 *in; 865 unsigned int, unsigned int,
1130 char num[5]; 866 unsigned int, int, int,
1131 int num2, cnt, out, found, save_cnt; 867 unsigned long);
1132 unsigned short in_tmp[8] = {0, }; 868void qeth_clear_ipacmd_list(struct qeth_card *);
1133 869int qeth_qdio_clear_card(struct qeth_card *, int);
1134 cnt = out = found = save_cnt = num2 = 0; 870void qeth_clear_working_pool_list(struct qeth_card *);
1135 end = start = buf; 871void qeth_clear_cmd_buffers(struct qeth_channel *);
1136 in = (__u16 *) addr; 872void qeth_clear_qdio_buffers(struct qeth_card *);
1137 memset(in, 0, 16); 873void qeth_setadp_promisc_mode(struct qeth_card *);
1138 while (*end) { 874struct net_device_stats *qeth_get_stats(struct net_device *);
1139 end = strchr(start,':'); 875int qeth_change_mtu(struct net_device *, int);
1140 if (end == NULL) { 876int qeth_setadpparms_change_macaddr(struct qeth_card *);
1141 end = buf + strlen(buf); 877void qeth_tx_timeout(struct net_device *);
1142 if ((end_tmp = strchr(start, '\n')) != NULL) 878void qeth_prepare_control_data(struct qeth_card *, int,
1143 end = end_tmp; 879 struct qeth_cmd_buffer *);
1144 out = 1; 880void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *);
1145 } 881void qeth_prepare_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, char);
1146 if ((end - start)) { 882struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
1147 memset(num, 0, 5); 883int qeth_mdio_read(struct net_device *, int, int);
1148 if ((end - start) > 4) 884int qeth_snmp_command(struct qeth_card *, char __user *);
1149 return -EINVAL; 885int qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
1150 memcpy(num, start, end - start); 886struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32);
1151 if (!qeth_isxdigit(num)) 887int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *,
1152 return -EINVAL; 888 unsigned long);
1153 sscanf(start, "%x", &num2); 889int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
1154 if (found) 890 int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long),
1155 in_tmp[save_cnt++] = num2; 891 void *reply_param);
1156 else 892int qeth_get_cast_type(struct qeth_card *, struct sk_buff *);
1157 in[cnt++] = num2; 893int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
1158 if (out) 894struct sk_buff *qeth_prepare_skb(struct qeth_card *, struct sk_buff *,
1159 break; 895 struct qeth_hdr **);
1160 } else { 896int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
1161 if (found) 897int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
1162 return -EINVAL; 898 struct sk_buff *, struct qeth_hdr *, int,
1163 found = 1; 899 struct qeth_eddp_context *);
1164 } 900int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
1165 start = ++end; 901 struct sk_buff *, struct qeth_hdr *,
1166 } 902 int, struct qeth_eddp_context *);
1167 if (cnt + save_cnt > 8) 903int qeth_core_get_stats_count(struct net_device *);
1168 return -EINVAL; 904void qeth_core_get_ethtool_stats(struct net_device *,
1169 cnt = 7; 905 struct ethtool_stats *, u64 *);
1170 while (save_cnt) 906void qeth_core_get_strings(struct net_device *, u32, u8 *);
1171 in[cnt--] = in_tmp[--save_cnt]; 907void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
1172 return 0; 908
1173} 909/* exports for OSN */
1174 910int qeth_osn_assist(struct net_device *, void *, int);
1175static inline void 911int qeth_osn_register(unsigned char *read_dev_no, struct net_device **,
1176qeth_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr, 912 int (*assist_cb)(struct net_device *, void *),
1177 char *buf) 913 int (*data_cb)(struct sk_buff *));
1178{ 914void qeth_osn_deregister(struct net_device *);
1179 if (proto == QETH_PROT_IPV4) 915
1180 qeth_ipaddr4_to_string(addr, buf); 916#endif /* __QETH_CORE_H__ */
1181 else if (proto == QETH_PROT_IPV6)
1182 qeth_ipaddr6_to_string(addr, buf);
1183}
1184
1185static inline int
1186qeth_string_to_ipaddr(const char *buf, enum qeth_prot_versions proto,
1187 __u8 *addr)
1188{
1189 if (proto == QETH_PROT_IPV4)
1190 return qeth_string_to_ipaddr4(buf, addr);
1191 else if (proto == QETH_PROT_IPV6)
1192 return qeth_string_to_ipaddr6(buf, addr);
1193 else
1194 return -EINVAL;
1195}
1196
1197extern int
1198qeth_setrouting_v4(struct qeth_card *);
1199extern int
1200qeth_setrouting_v6(struct qeth_card *);
1201
1202extern int
1203qeth_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *);
1204
1205extern void
1206qeth_del_ipato_entry(struct qeth_card *, enum qeth_prot_versions, u8 *, int);
1207
1208extern int
1209qeth_add_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
1210
1211extern void
1212qeth_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
1213
1214extern int
1215qeth_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
1216
1217extern void
1218qeth_del_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
1219
1220extern int
1221qeth_notifier_register(struct task_struct *, int );
1222
1223extern int
1224qeth_notifier_unregister(struct task_struct * );
1225
1226extern void
1227qeth_schedule_recovery(struct qeth_card *);
1228
1229extern int
1230qeth_realloc_buffer_pool(struct qeth_card *, int);
1231
1232extern int
1233qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
1234
1235extern void
1236qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
1237 struct sk_buff *, int, int);
1238extern void
1239qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int);
1240
1241extern int
1242qeth_osn_assist(struct net_device *, void *, int);
1243
1244extern int
1245qeth_osn_register(unsigned char *read_dev_no,
1246 struct net_device **,
1247 int (*assist_cb)(struct net_device *, void *),
1248 int (*data_cb)(struct sk_buff *));
1249
1250extern void
1251qeth_osn_deregister(struct net_device *);
1252
1253#endif /* __QETH_H__ */
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
new file mode 100644
index 000000000000..95c6fcf58953
--- /dev/null
+++ b/drivers/s390/net/qeth_core_main.c
@@ -0,0 +1,4540 @@
1/*
2 * drivers/s390/net/qeth_core_main.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/string.h>
14#include <linux/errno.h>
15#include <linux/kernel.h>
16#include <linux/ip.h>
17#include <linux/ipv6.h>
18#include <linux/tcp.h>
19#include <linux/mii.h>
20#include <linux/kthread.h>
21
22#include <asm-s390/ebcdic.h>
23#include <asm-s390/io.h>
24#include <asm/s390_rdev.h>
25
26#include "qeth_core.h"
27#include "qeth_core_offl.h"
28
29#define QETH_DBF_TEXT_(name, level, text...) \
30 do { \
31 if (qeth_dbf_passes(qeth_dbf_##name, level)) { \
32 char *dbf_txt_buf = \
33 get_cpu_var(qeth_core_dbf_txt_buf); \
34 sprintf(dbf_txt_buf, text); \
35 debug_text_event(qeth_dbf_##name, level, dbf_txt_buf); \
36 put_cpu_var(qeth_core_dbf_txt_buf); \
37 } \
38 } while (0)
39
40struct qeth_card_list_struct qeth_core_card_list;
41EXPORT_SYMBOL_GPL(qeth_core_card_list);
42debug_info_t *qeth_dbf_setup;
43EXPORT_SYMBOL_GPL(qeth_dbf_setup);
44debug_info_t *qeth_dbf_data;
45EXPORT_SYMBOL_GPL(qeth_dbf_data);
46debug_info_t *qeth_dbf_misc;
47EXPORT_SYMBOL_GPL(qeth_dbf_misc);
48debug_info_t *qeth_dbf_control;
49EXPORT_SYMBOL_GPL(qeth_dbf_control);
50debug_info_t *qeth_dbf_trace;
51EXPORT_SYMBOL_GPL(qeth_dbf_trace);
52debug_info_t *qeth_dbf_sense;
53EXPORT_SYMBOL_GPL(qeth_dbf_sense);
54debug_info_t *qeth_dbf_qerr;
55EXPORT_SYMBOL_GPL(qeth_dbf_qerr);
56
57static struct device *qeth_core_root_dev;
58static unsigned int known_devices[][10] = QETH_MODELLIST_ARRAY;
59static struct lock_class_key qdio_out_skb_queue_key;
60static DEFINE_PER_CPU(char[256], qeth_core_dbf_txt_buf);
61
62static void qeth_send_control_data_cb(struct qeth_channel *,
63 struct qeth_cmd_buffer *);
64static int qeth_issue_next_read(struct qeth_card *);
65static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *);
66static void qeth_setup_ccw(struct qeth_channel *, unsigned char *, __u32);
67static void qeth_free_buffer_pool(struct qeth_card *);
68static int qeth_qdio_establish(struct qeth_card *);
69
70
71static inline void __qeth_fill_buffer_frag(struct sk_buff *skb,
72 struct qdio_buffer *buffer, int is_tso,
73 int *next_element_to_fill)
74{
75 struct skb_frag_struct *frag;
76 int fragno;
77 unsigned long addr;
78 int element, cnt, dlen;
79
80 fragno = skb_shinfo(skb)->nr_frags;
81 element = *next_element_to_fill;
82 dlen = 0;
83
84 if (is_tso)
85 buffer->element[element].flags =
86 SBAL_FLAGS_MIDDLE_FRAG;
87 else
88 buffer->element[element].flags =
89 SBAL_FLAGS_FIRST_FRAG;
90 dlen = skb->len - skb->data_len;
91 if (dlen) {
92 buffer->element[element].addr = skb->data;
93 buffer->element[element].length = dlen;
94 element++;
95 }
96 for (cnt = 0; cnt < fragno; cnt++) {
97 frag = &skb_shinfo(skb)->frags[cnt];
98 addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
99 frag->page_offset;
100 buffer->element[element].addr = (char *)addr;
101 buffer->element[element].length = frag->size;
102 if (cnt < (fragno - 1))
103 buffer->element[element].flags =
104 SBAL_FLAGS_MIDDLE_FRAG;
105 else
106 buffer->element[element].flags =
107 SBAL_FLAGS_LAST_FRAG;
108 element++;
109 }
110 *next_element_to_fill = element;
111}
112
113static inline const char *qeth_get_cardname(struct qeth_card *card)
114{
115 if (card->info.guestlan) {
116 switch (card->info.type) {
117 case QETH_CARD_TYPE_OSAE:
118 return " Guest LAN QDIO";
119 case QETH_CARD_TYPE_IQD:
120 return " Guest LAN Hiper";
121 default:
122 return " unknown";
123 }
124 } else {
125 switch (card->info.type) {
126 case QETH_CARD_TYPE_OSAE:
127 return " OSD Express";
128 case QETH_CARD_TYPE_IQD:
129 return " HiperSockets";
130 case QETH_CARD_TYPE_OSN:
131 return " OSN QDIO";
132 default:
133 return " unknown";
134 }
135 }
136 return " n/a";
137}
138
139/* max length to be returned: 14 */
140const char *qeth_get_cardname_short(struct qeth_card *card)
141{
142 if (card->info.guestlan) {
143 switch (card->info.type) {
144 case QETH_CARD_TYPE_OSAE:
145 return "GuestLAN QDIO";
146 case QETH_CARD_TYPE_IQD:
147 return "GuestLAN Hiper";
148 default:
149 return "unknown";
150 }
151 } else {
152 switch (card->info.type) {
153 case QETH_CARD_TYPE_OSAE:
154 switch (card->info.link_type) {
155 case QETH_LINK_TYPE_FAST_ETH:
156 return "OSD_100";
157 case QETH_LINK_TYPE_HSTR:
158 return "HSTR";
159 case QETH_LINK_TYPE_GBIT_ETH:
160 return "OSD_1000";
161 case QETH_LINK_TYPE_10GBIT_ETH:
162 return "OSD_10GIG";
163 case QETH_LINK_TYPE_LANE_ETH100:
164 return "OSD_FE_LANE";
165 case QETH_LINK_TYPE_LANE_TR:
166 return "OSD_TR_LANE";
167 case QETH_LINK_TYPE_LANE_ETH1000:
168 return "OSD_GbE_LANE";
169 case QETH_LINK_TYPE_LANE:
170 return "OSD_ATM_LANE";
171 default:
172 return "OSD_Express";
173 }
174 case QETH_CARD_TYPE_IQD:
175 return "HiperSockets";
176 case QETH_CARD_TYPE_OSN:
177 return "OSN";
178 default:
179 return "unknown";
180 }
181 }
182 return "n/a";
183}
184
185void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
186 int clear_start_mask)
187{
188 unsigned long flags;
189
190 spin_lock_irqsave(&card->thread_mask_lock, flags);
191 card->thread_allowed_mask = threads;
192 if (clear_start_mask)
193 card->thread_start_mask &= threads;
194 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
195 wake_up(&card->wait_q);
196}
197EXPORT_SYMBOL_GPL(qeth_set_allowed_threads);
198
199int qeth_threads_running(struct qeth_card *card, unsigned long threads)
200{
201 unsigned long flags;
202 int rc = 0;
203
204 spin_lock_irqsave(&card->thread_mask_lock, flags);
205 rc = (card->thread_running_mask & threads);
206 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
207 return rc;
208}
209EXPORT_SYMBOL_GPL(qeth_threads_running);
210
211int qeth_wait_for_threads(struct qeth_card *card, unsigned long threads)
212{
213 return wait_event_interruptible(card->wait_q,
214 qeth_threads_running(card, threads) == 0);
215}
216EXPORT_SYMBOL_GPL(qeth_wait_for_threads);
217
218void qeth_clear_working_pool_list(struct qeth_card *card)
219{
220 struct qeth_buffer_pool_entry *pool_entry, *tmp;
221
222 QETH_DBF_TEXT(trace, 5, "clwrklst");
223 list_for_each_entry_safe(pool_entry, tmp,
224 &card->qdio.in_buf_pool.entry_list, list){
225 list_del(&pool_entry->list);
226 }
227}
228EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list);
229
230static int qeth_alloc_buffer_pool(struct qeth_card *card)
231{
232 struct qeth_buffer_pool_entry *pool_entry;
233 void *ptr;
234 int i, j;
235
236 QETH_DBF_TEXT(trace, 5, "alocpool");
237 for (i = 0; i < card->qdio.init_pool.buf_count; ++i) {
238 pool_entry = kmalloc(sizeof(*pool_entry), GFP_KERNEL);
239 if (!pool_entry) {
240 qeth_free_buffer_pool(card);
241 return -ENOMEM;
242 }
243 for (j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j) {
244 ptr = (void *) __get_free_page(GFP_KERNEL|GFP_DMA);
245 if (!ptr) {
246 while (j > 0)
247 free_page((unsigned long)
248 pool_entry->elements[--j]);
249 kfree(pool_entry);
250 qeth_free_buffer_pool(card);
251 return -ENOMEM;
252 }
253 pool_entry->elements[j] = ptr;
254 }
255 list_add(&pool_entry->init_list,
256 &card->qdio.init_pool.entry_list);
257 }
258 return 0;
259}
260
261int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
262{
263 QETH_DBF_TEXT(trace, 2, "realcbp");
264
265 if ((card->state != CARD_STATE_DOWN) &&
266 (card->state != CARD_STATE_RECOVER))
267 return -EPERM;
268
269 /* TODO: steel/add buffers from/to a running card's buffer pool (?) */
270 qeth_clear_working_pool_list(card);
271 qeth_free_buffer_pool(card);
272 card->qdio.in_buf_pool.buf_count = bufcnt;
273 card->qdio.init_pool.buf_count = bufcnt;
274 return qeth_alloc_buffer_pool(card);
275}
276
277int qeth_set_large_send(struct qeth_card *card,
278 enum qeth_large_send_types type)
279{
280 int rc = 0;
281
282 if (card->dev == NULL) {
283 card->options.large_send = type;
284 return 0;
285 }
286 if (card->state == CARD_STATE_UP)
287 netif_tx_disable(card->dev);
288 card->options.large_send = type;
289 switch (card->options.large_send) {
290 case QETH_LARGE_SEND_EDDP:
291 card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
292 NETIF_F_HW_CSUM;
293 break;
294 case QETH_LARGE_SEND_TSO:
295 if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
296 card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
297 NETIF_F_HW_CSUM;
298 } else {
299 PRINT_WARN("TSO not supported on %s. "
300 "large_send set to 'no'.\n",
301 card->dev->name);
302 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
303 NETIF_F_HW_CSUM);
304 card->options.large_send = QETH_LARGE_SEND_NO;
305 rc = -EOPNOTSUPP;
306 }
307 break;
308 default: /* includes QETH_LARGE_SEND_NO */
309 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
310 NETIF_F_HW_CSUM);
311 break;
312 }
313 if (card->state == CARD_STATE_UP)
314 netif_wake_queue(card->dev);
315 return rc;
316}
317EXPORT_SYMBOL_GPL(qeth_set_large_send);
318
319static int qeth_issue_next_read(struct qeth_card *card)
320{
321 int rc;
322 struct qeth_cmd_buffer *iob;
323
324 QETH_DBF_TEXT(trace, 5, "issnxrd");
325 if (card->read.state != CH_STATE_UP)
326 return -EIO;
327 iob = qeth_get_buffer(&card->read);
328 if (!iob) {
329 PRINT_WARN("issue_next_read failed: no iob available!\n");
330 return -ENOMEM;
331 }
332 qeth_setup_ccw(&card->read, iob->data, QETH_BUFSIZE);
333 QETH_DBF_TEXT(trace, 6, "noirqpnd");
334 rc = ccw_device_start(card->read.ccwdev, &card->read.ccw,
335 (addr_t) iob, 0, 0);
336 if (rc) {
337 PRINT_ERR("Error in starting next read ccw! rc=%i\n", rc);
338 atomic_set(&card->read.irq_pending, 0);
339 qeth_schedule_recovery(card);
340 wake_up(&card->wait_q);
341 }
342 return rc;
343}
344
345static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
346{
347 struct qeth_reply *reply;
348
349 reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
350 if (reply) {
351 atomic_set(&reply->refcnt, 1);
352 atomic_set(&reply->received, 0);
353 reply->card = card;
354 };
355 return reply;
356}
357
358static void qeth_get_reply(struct qeth_reply *reply)
359{
360 WARN_ON(atomic_read(&reply->refcnt) <= 0);
361 atomic_inc(&reply->refcnt);
362}
363
364static void qeth_put_reply(struct qeth_reply *reply)
365{
366 WARN_ON(atomic_read(&reply->refcnt) <= 0);
367 if (atomic_dec_and_test(&reply->refcnt))
368 kfree(reply);
369}
370
371static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd,
372 struct qeth_card *card)
373{
374 int rc;
375 int com;
376 char *ipa_name;
377
378 com = cmd->hdr.command;
379 rc = cmd->hdr.return_code;
380 ipa_name = qeth_get_ipa_cmd_name(com);
381
382 PRINT_ERR("%s(x%X) for %s returned x%X \"%s\"\n", ipa_name, com,
383 QETH_CARD_IFNAME(card), rc, qeth_get_ipa_msg(rc));
384}
385
386static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
387 struct qeth_cmd_buffer *iob)
388{
389 struct qeth_ipa_cmd *cmd = NULL;
390
391 QETH_DBF_TEXT(trace, 5, "chkipad");
392 if (IS_IPA(iob->data)) {
393 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
394 if (IS_IPA_REPLY(cmd)) {
395 if (cmd->hdr.return_code &&
396 (cmd->hdr.command < IPA_CMD_SETCCID ||
397 cmd->hdr.command > IPA_CMD_MODCCID))
398 qeth_issue_ipa_msg(cmd, card);
399 return cmd;
400 } else {
401 switch (cmd->hdr.command) {
402 case IPA_CMD_STOPLAN:
403 PRINT_WARN("Link failure on %s (CHPID 0x%X) - "
404 "there is a network problem or "
405 "someone pulled the cable or "
406 "disabled the port.\n",
407 QETH_CARD_IFNAME(card),
408 card->info.chpid);
409 card->lan_online = 0;
410 if (card->dev && netif_carrier_ok(card->dev))
411 netif_carrier_off(card->dev);
412 return NULL;
413 case IPA_CMD_STARTLAN:
414 PRINT_INFO("Link reestablished on %s "
415 "(CHPID 0x%X). Scheduling "
416 "IP address reset.\n",
417 QETH_CARD_IFNAME(card),
418 card->info.chpid);
419 netif_carrier_on(card->dev);
420 qeth_schedule_recovery(card);
421 return NULL;
422 case IPA_CMD_MODCCID:
423 return cmd;
424 case IPA_CMD_REGISTER_LOCAL_ADDR:
425 QETH_DBF_TEXT(trace, 3, "irla");
426 break;
427 case IPA_CMD_UNREGISTER_LOCAL_ADDR:
428 QETH_DBF_TEXT(trace, 3, "urla");
429 break;
430 default:
431 PRINT_WARN("Received data is IPA "
432 "but not a reply!\n");
433 break;
434 }
435 }
436 }
437 return cmd;
438}
439
440void qeth_clear_ipacmd_list(struct qeth_card *card)
441{
442 struct qeth_reply *reply, *r;
443 unsigned long flags;
444
445 QETH_DBF_TEXT(trace, 4, "clipalst");
446
447 spin_lock_irqsave(&card->lock, flags);
448 list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
449 qeth_get_reply(reply);
450 reply->rc = -EIO;
451 atomic_inc(&reply->received);
452 list_del_init(&reply->list);
453 wake_up(&reply->wait_q);
454 qeth_put_reply(reply);
455 }
456 spin_unlock_irqrestore(&card->lock, flags);
457}
458EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
459
460static int qeth_check_idx_response(unsigned char *buffer)
461{
462 if (!buffer)
463 return 0;
464
465 QETH_DBF_HEX(control, 2, buffer, QETH_DBF_CONTROL_LEN);
466 if ((buffer[2] & 0xc0) == 0xc0) {
467 PRINT_WARN("received an IDX TERMINATE "
468 "with cause code 0x%02x%s\n",
469 buffer[4],
470 ((buffer[4] == 0x22) ?
471 " -- try another portname" : ""));
472 QETH_DBF_TEXT(trace, 2, "ckidxres");
473 QETH_DBF_TEXT(trace, 2, " idxterm");
474 QETH_DBF_TEXT_(trace, 2, " rc%d", -EIO);
475 return -EIO;
476 }
477 return 0;
478}
479
480static void qeth_setup_ccw(struct qeth_channel *channel, unsigned char *iob,
481 __u32 len)
482{
483 struct qeth_card *card;
484
485 QETH_DBF_TEXT(trace, 4, "setupccw");
486 card = CARD_FROM_CDEV(channel->ccwdev);
487 if (channel == &card->read)
488 memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1));
489 else
490 memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1));
491 channel->ccw.count = len;
492 channel->ccw.cda = (__u32) __pa(iob);
493}
494
495static struct qeth_cmd_buffer *__qeth_get_buffer(struct qeth_channel *channel)
496{
497 __u8 index;
498
499 QETH_DBF_TEXT(trace, 6, "getbuff");
500 index = channel->io_buf_no;
501 do {
502 if (channel->iob[index].state == BUF_STATE_FREE) {
503 channel->iob[index].state = BUF_STATE_LOCKED;
504 channel->io_buf_no = (channel->io_buf_no + 1) %
505 QETH_CMD_BUFFER_NO;
506 memset(channel->iob[index].data, 0, QETH_BUFSIZE);
507 return channel->iob + index;
508 }
509 index = (index + 1) % QETH_CMD_BUFFER_NO;
510 } while (index != channel->io_buf_no);
511
512 return NULL;
513}
514
515void qeth_release_buffer(struct qeth_channel *channel,
516 struct qeth_cmd_buffer *iob)
517{
518 unsigned long flags;
519
520 QETH_DBF_TEXT(trace, 6, "relbuff");
521 spin_lock_irqsave(&channel->iob_lock, flags);
522 memset(iob->data, 0, QETH_BUFSIZE);
523 iob->state = BUF_STATE_FREE;
524 iob->callback = qeth_send_control_data_cb;
525 iob->rc = 0;
526 spin_unlock_irqrestore(&channel->iob_lock, flags);
527}
528EXPORT_SYMBOL_GPL(qeth_release_buffer);
529
530static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel)
531{
532 struct qeth_cmd_buffer *buffer = NULL;
533 unsigned long flags;
534
535 spin_lock_irqsave(&channel->iob_lock, flags);
536 buffer = __qeth_get_buffer(channel);
537 spin_unlock_irqrestore(&channel->iob_lock, flags);
538 return buffer;
539}
540
541struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *channel)
542{
543 struct qeth_cmd_buffer *buffer;
544 wait_event(channel->wait_q,
545 ((buffer = qeth_get_buffer(channel)) != NULL));
546 return buffer;
547}
548EXPORT_SYMBOL_GPL(qeth_wait_for_buffer);
549
550void qeth_clear_cmd_buffers(struct qeth_channel *channel)
551{
552 int cnt;
553
554 for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++)
555 qeth_release_buffer(channel, &channel->iob[cnt]);
556 channel->buf_no = 0;
557 channel->io_buf_no = 0;
558}
559EXPORT_SYMBOL_GPL(qeth_clear_cmd_buffers);
560
561static void qeth_send_control_data_cb(struct qeth_channel *channel,
562 struct qeth_cmd_buffer *iob)
563{
564 struct qeth_card *card;
565 struct qeth_reply *reply, *r;
566 struct qeth_ipa_cmd *cmd;
567 unsigned long flags;
568 int keep_reply;
569
570 QETH_DBF_TEXT(trace, 4, "sndctlcb");
571
572 card = CARD_FROM_CDEV(channel->ccwdev);
573 if (qeth_check_idx_response(iob->data)) {
574 qeth_clear_ipacmd_list(card);
575 qeth_schedule_recovery(card);
576 goto out;
577 }
578
579 cmd = qeth_check_ipa_data(card, iob);
580 if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
581 goto out;
582 /*in case of OSN : check if cmd is set */
583 if (card->info.type == QETH_CARD_TYPE_OSN &&
584 cmd &&
585 cmd->hdr.command != IPA_CMD_STARTLAN &&
586 card->osn_info.assist_cb != NULL) {
587 card->osn_info.assist_cb(card->dev, cmd);
588 goto out;
589 }
590
591 spin_lock_irqsave(&card->lock, flags);
592 list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
593 if ((reply->seqno == QETH_IDX_COMMAND_SEQNO) ||
594 ((cmd) && (reply->seqno == cmd->hdr.seqno))) {
595 qeth_get_reply(reply);
596 list_del_init(&reply->list);
597 spin_unlock_irqrestore(&card->lock, flags);
598 keep_reply = 0;
599 if (reply->callback != NULL) {
600 if (cmd) {
601 reply->offset = (__u16)((char *)cmd -
602 (char *)iob->data);
603 keep_reply = reply->callback(card,
604 reply,
605 (unsigned long)cmd);
606 } else
607 keep_reply = reply->callback(card,
608 reply,
609 (unsigned long)iob);
610 }
611 if (cmd)
612 reply->rc = (u16) cmd->hdr.return_code;
613 else if (iob->rc)
614 reply->rc = iob->rc;
615 if (keep_reply) {
616 spin_lock_irqsave(&card->lock, flags);
617 list_add_tail(&reply->list,
618 &card->cmd_waiter_list);
619 spin_unlock_irqrestore(&card->lock, flags);
620 } else {
621 atomic_inc(&reply->received);
622 wake_up(&reply->wait_q);
623 }
624 qeth_put_reply(reply);
625 goto out;
626 }
627 }
628 spin_unlock_irqrestore(&card->lock, flags);
629out:
630 memcpy(&card->seqno.pdu_hdr_ack,
631 QETH_PDU_HEADER_SEQ_NO(iob->data),
632 QETH_SEQ_NO_LENGTH);
633 qeth_release_buffer(channel, iob);
634}
635
636static int qeth_setup_channel(struct qeth_channel *channel)
637{
638 int cnt;
639
640 QETH_DBF_TEXT(setup, 2, "setupch");
641 for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) {
642 channel->iob[cnt].data = (char *)
643 kmalloc(QETH_BUFSIZE, GFP_DMA|GFP_KERNEL);
644 if (channel->iob[cnt].data == NULL)
645 break;
646 channel->iob[cnt].state = BUF_STATE_FREE;
647 channel->iob[cnt].channel = channel;
648 channel->iob[cnt].callback = qeth_send_control_data_cb;
649 channel->iob[cnt].rc = 0;
650 }
651 if (cnt < QETH_CMD_BUFFER_NO) {
652 while (cnt-- > 0)
653 kfree(channel->iob[cnt].data);
654 return -ENOMEM;
655 }
656 channel->buf_no = 0;
657 channel->io_buf_no = 0;
658 atomic_set(&channel->irq_pending, 0);
659 spin_lock_init(&channel->iob_lock);
660
661 init_waitqueue_head(&channel->wait_q);
662 return 0;
663}
664
665static int qeth_set_thread_start_bit(struct qeth_card *card,
666 unsigned long thread)
667{
668 unsigned long flags;
669
670 spin_lock_irqsave(&card->thread_mask_lock, flags);
671 if (!(card->thread_allowed_mask & thread) ||
672 (card->thread_start_mask & thread)) {
673 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
674 return -EPERM;
675 }
676 card->thread_start_mask |= thread;
677 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
678 return 0;
679}
680
681void qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread)
682{
683 unsigned long flags;
684
685 spin_lock_irqsave(&card->thread_mask_lock, flags);
686 card->thread_start_mask &= ~thread;
687 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
688 wake_up(&card->wait_q);
689}
690EXPORT_SYMBOL_GPL(qeth_clear_thread_start_bit);
691
692void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
693{
694 unsigned long flags;
695
696 spin_lock_irqsave(&card->thread_mask_lock, flags);
697 card->thread_running_mask &= ~thread;
698 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
699 wake_up(&card->wait_q);
700}
701EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);
702
703static int __qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
704{
705 unsigned long flags;
706 int rc = 0;
707
708 spin_lock_irqsave(&card->thread_mask_lock, flags);
709 if (card->thread_start_mask & thread) {
710 if ((card->thread_allowed_mask & thread) &&
711 !(card->thread_running_mask & thread)) {
712 rc = 1;
713 card->thread_start_mask &= ~thread;
714 card->thread_running_mask |= thread;
715 } else
716 rc = -EPERM;
717 }
718 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
719 return rc;
720}
721
722int qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
723{
724 int rc = 0;
725
726 wait_event(card->wait_q,
727 (rc = __qeth_do_run_thread(card, thread)) >= 0);
728 return rc;
729}
730EXPORT_SYMBOL_GPL(qeth_do_run_thread);
731
732void qeth_schedule_recovery(struct qeth_card *card)
733{
734 QETH_DBF_TEXT(trace, 2, "startrec");
735 if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
736 schedule_work(&card->kernel_thread_starter);
737}
738EXPORT_SYMBOL_GPL(qeth_schedule_recovery);
739
740static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
741{
742 int dstat, cstat;
743 char *sense;
744
745 sense = (char *) irb->ecw;
746 cstat = irb->scsw.cstat;
747 dstat = irb->scsw.dstat;
748
749 if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
750 SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
751 SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
752 QETH_DBF_TEXT(trace, 2, "CGENCHK");
753 PRINT_WARN("check on device %s, dstat=x%x, cstat=x%x ",
754 cdev->dev.bus_id, dstat, cstat);
755 print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET,
756 16, 1, irb, 64, 1);
757 return 1;
758 }
759
760 if (dstat & DEV_STAT_UNIT_CHECK) {
761 if (sense[SENSE_RESETTING_EVENT_BYTE] &
762 SENSE_RESETTING_EVENT_FLAG) {
763 QETH_DBF_TEXT(trace, 2, "REVIND");
764 return 1;
765 }
766 if (sense[SENSE_COMMAND_REJECT_BYTE] &
767 SENSE_COMMAND_REJECT_FLAG) {
768 QETH_DBF_TEXT(trace, 2, "CMDREJi");
769 return 0;
770 }
771 if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) {
772 QETH_DBF_TEXT(trace, 2, "AFFE");
773 return 1;
774 }
775 if ((!sense[0]) && (!sense[1]) && (!sense[2]) && (!sense[3])) {
776 QETH_DBF_TEXT(trace, 2, "ZEROSEN");
777 return 0;
778 }
779 QETH_DBF_TEXT(trace, 2, "DGENCHK");
780 return 1;
781 }
782 return 0;
783}
784
785static long __qeth_check_irb_error(struct ccw_device *cdev,
786 unsigned long intparm, struct irb *irb)
787{
788 if (!IS_ERR(irb))
789 return 0;
790
791 switch (PTR_ERR(irb)) {
792 case -EIO:
793 PRINT_WARN("i/o-error on device %s\n", cdev->dev.bus_id);
794 QETH_DBF_TEXT(trace, 2, "ckirberr");
795 QETH_DBF_TEXT_(trace, 2, " rc%d", -EIO);
796 break;
797 case -ETIMEDOUT:
798 PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id);
799 QETH_DBF_TEXT(trace, 2, "ckirberr");
800 QETH_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT);
801 if (intparm == QETH_RCD_PARM) {
802 struct qeth_card *card = CARD_FROM_CDEV(cdev);
803
804 if (card && (card->data.ccwdev == cdev)) {
805 card->data.state = CH_STATE_DOWN;
806 wake_up(&card->wait_q);
807 }
808 }
809 break;
810 default:
811 PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb),
812 cdev->dev.bus_id);
813 QETH_DBF_TEXT(trace, 2, "ckirberr");
814 QETH_DBF_TEXT(trace, 2, " rc???");
815 }
816 return PTR_ERR(irb);
817}
818
819static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
820 struct irb *irb)
821{
822 int rc;
823 int cstat, dstat;
824 struct qeth_cmd_buffer *buffer;
825 struct qeth_channel *channel;
826 struct qeth_card *card;
827 struct qeth_cmd_buffer *iob;
828 __u8 index;
829
830 QETH_DBF_TEXT(trace, 5, "irq");
831
832 if (__qeth_check_irb_error(cdev, intparm, irb))
833 return;
834 cstat = irb->scsw.cstat;
835 dstat = irb->scsw.dstat;
836
837 card = CARD_FROM_CDEV(cdev);
838 if (!card)
839 return;
840
841 if (card->read.ccwdev == cdev) {
842 channel = &card->read;
843 QETH_DBF_TEXT(trace, 5, "read");
844 } else if (card->write.ccwdev == cdev) {
845 channel = &card->write;
846 QETH_DBF_TEXT(trace, 5, "write");
847 } else {
848 channel = &card->data;
849 QETH_DBF_TEXT(trace, 5, "data");
850 }
851 atomic_set(&channel->irq_pending, 0);
852
853 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC))
854 channel->state = CH_STATE_STOPPED;
855
856 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC))
857 channel->state = CH_STATE_HALTED;
858
859 /*let's wake up immediately on data channel*/
860 if ((channel == &card->data) && (intparm != 0) &&
861 (intparm != QETH_RCD_PARM))
862 goto out;
863
864 if (intparm == QETH_CLEAR_CHANNEL_PARM) {
865 QETH_DBF_TEXT(trace, 6, "clrchpar");
866 /* we don't have to handle this further */
867 intparm = 0;
868 }
869 if (intparm == QETH_HALT_CHANNEL_PARM) {
870 QETH_DBF_TEXT(trace, 6, "hltchpar");
871 /* we don't have to handle this further */
872 intparm = 0;
873 }
874 if ((dstat & DEV_STAT_UNIT_EXCEP) ||
875 (dstat & DEV_STAT_UNIT_CHECK) ||
876 (cstat)) {
877 if (irb->esw.esw0.erw.cons) {
878 /* TODO: we should make this s390dbf */
879 PRINT_WARN("sense data available on channel %s.\n",
880 CHANNEL_ID(channel));
881 PRINT_WARN(" cstat 0x%X\n dstat 0x%X\n", cstat, dstat);
882 print_hex_dump(KERN_WARNING, "qeth: irb ",
883 DUMP_PREFIX_OFFSET, 16, 1, irb, 32, 1);
884 print_hex_dump(KERN_WARNING, "qeth: sense data ",
885 DUMP_PREFIX_OFFSET, 16, 1, irb->ecw, 32, 1);
886 }
887 if (intparm == QETH_RCD_PARM) {
888 channel->state = CH_STATE_DOWN;
889 goto out;
890 }
891 rc = qeth_get_problem(cdev, irb);
892 if (rc) {
893 qeth_schedule_recovery(card);
894 goto out;
895 }
896 }
897
898 if (intparm == QETH_RCD_PARM) {
899 channel->state = CH_STATE_RCD_DONE;
900 goto out;
901 }
902 if (intparm) {
903 buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
904 buffer->state = BUF_STATE_PROCESSED;
905 }
906 if (channel == &card->data)
907 return;
908 if (channel == &card->read &&
909 channel->state == CH_STATE_UP)
910 qeth_issue_next_read(card);
911
912 iob = channel->iob;
913 index = channel->buf_no;
914 while (iob[index].state == BUF_STATE_PROCESSED) {
915 if (iob[index].callback != NULL)
916 iob[index].callback(channel, iob + index);
917
918 index = (index + 1) % QETH_CMD_BUFFER_NO;
919 }
920 channel->buf_no = index;
921out:
922 wake_up(&card->wait_q);
923 return;
924}
925
926static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
927 struct qeth_qdio_out_buffer *buf)
928{
929 int i;
930 struct sk_buff *skb;
931
932 /* is PCI flag set on buffer? */
933 if (buf->buffer->element[0].flags & 0x40)
934 atomic_dec(&queue->set_pci_flags_count);
935
936 skb = skb_dequeue(&buf->skb_list);
937 while (skb) {
938 atomic_dec(&skb->users);
939 dev_kfree_skb_any(skb);
940 skb = skb_dequeue(&buf->skb_list);
941 }
942 qeth_eddp_buf_release_contexts(buf);
943 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
944 buf->buffer->element[i].length = 0;
945 buf->buffer->element[i].addr = NULL;
946 buf->buffer->element[i].flags = 0;
947 }
948 buf->next_element_to_fill = 0;
949 atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
950}
951
952void qeth_clear_qdio_buffers(struct qeth_card *card)
953{
954 int i, j;
955
956 QETH_DBF_TEXT(trace, 2, "clearqdbf");
957 /* clear outbound buffers to free skbs */
958 for (i = 0; i < card->qdio.no_out_queues; ++i)
959 if (card->qdio.out_qs[i]) {
960 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
961 qeth_clear_output_buffer(card->qdio.out_qs[i],
962 &card->qdio.out_qs[i]->bufs[j]);
963 }
964}
965EXPORT_SYMBOL_GPL(qeth_clear_qdio_buffers);
966
967static void qeth_free_buffer_pool(struct qeth_card *card)
968{
969 struct qeth_buffer_pool_entry *pool_entry, *tmp;
970 int i = 0;
971 QETH_DBF_TEXT(trace, 5, "freepool");
972 list_for_each_entry_safe(pool_entry, tmp,
973 &card->qdio.init_pool.entry_list, init_list){
974 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i)
975 free_page((unsigned long)pool_entry->elements[i]);
976 list_del(&pool_entry->init_list);
977 kfree(pool_entry);
978 }
979}
980
981static void qeth_free_qdio_buffers(struct qeth_card *card)
982{
983 int i, j;
984
985 QETH_DBF_TEXT(trace, 2, "freeqdbf");
986 if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
987 QETH_QDIO_UNINITIALIZED)
988 return;
989 kfree(card->qdio.in_q);
990 card->qdio.in_q = NULL;
991 /* inbound buffer pool */
992 qeth_free_buffer_pool(card);
993 /* free outbound qdio_qs */
994 if (card->qdio.out_qs) {
995 for (i = 0; i < card->qdio.no_out_queues; ++i) {
996 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
997 qeth_clear_output_buffer(card->qdio.out_qs[i],
998 &card->qdio.out_qs[i]->bufs[j]);
999 kfree(card->qdio.out_qs[i]);
1000 }
1001 kfree(card->qdio.out_qs);
1002 card->qdio.out_qs = NULL;
1003 }
1004}
1005
1006static void qeth_clean_channel(struct qeth_channel *channel)
1007{
1008 int cnt;
1009
1010 QETH_DBF_TEXT(setup, 2, "freech");
1011 for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++)
1012 kfree(channel->iob[cnt].data);
1013}
1014
1015static int qeth_is_1920_device(struct qeth_card *card)
1016{
1017 int single_queue = 0;
1018 struct ccw_device *ccwdev;
1019 struct channelPath_dsc {
1020 u8 flags;
1021 u8 lsn;
1022 u8 desc;
1023 u8 chpid;
1024 u8 swla;
1025 u8 zeroes;
1026 u8 chla;
1027 u8 chpp;
1028 } *chp_dsc;
1029
1030 QETH_DBF_TEXT(setup, 2, "chk_1920");
1031
1032 ccwdev = card->data.ccwdev;
1033 chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0);
1034 if (chp_dsc != NULL) {
1035 /* CHPP field bit 6 == 1 -> single queue */
1036 single_queue = ((chp_dsc->chpp & 0x02) == 0x02);
1037 kfree(chp_dsc);
1038 }
1039 QETH_DBF_TEXT_(setup, 2, "rc:%x", single_queue);
1040 return single_queue;
1041}
1042
1043static void qeth_init_qdio_info(struct qeth_card *card)
1044{
1045 QETH_DBF_TEXT(setup, 4, "intqdinf");
1046 atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
1047 /* inbound */
1048 card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
1049 card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT;
1050 card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
1051 INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
1052 INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
1053}
1054
1055static void qeth_set_intial_options(struct qeth_card *card)
1056{
1057 card->options.route4.type = NO_ROUTER;
1058 card->options.route6.type = NO_ROUTER;
1059 card->options.checksum_type = QETH_CHECKSUM_DEFAULT;
1060 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
1061 card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
1062 card->options.fake_broadcast = 0;
1063 card->options.add_hhlen = DEFAULT_ADD_HHLEN;
1064 card->options.fake_ll = 0;
1065 card->options.performance_stats = 0;
1066 card->options.rx_sg_cb = QETH_RX_SG_CB;
1067}
1068
1069static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
1070{
1071 unsigned long flags;
1072 int rc = 0;
1073
1074 spin_lock_irqsave(&card->thread_mask_lock, flags);
1075 QETH_DBF_TEXT_(trace, 4, " %02x%02x%02x",
1076 (u8) card->thread_start_mask,
1077 (u8) card->thread_allowed_mask,
1078 (u8) card->thread_running_mask);
1079 rc = (card->thread_start_mask & thread);
1080 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
1081 return rc;
1082}
1083
1084static void qeth_start_kernel_thread(struct work_struct *work)
1085{
1086 struct qeth_card *card = container_of(work, struct qeth_card,
1087 kernel_thread_starter);
1088 QETH_DBF_TEXT(trace , 2, "strthrd");
1089
1090 if (card->read.state != CH_STATE_UP &&
1091 card->write.state != CH_STATE_UP)
1092 return;
1093 if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
1094 kthread_run(card->discipline.recover, (void *) card,
1095 "qeth_recover");
1096}
1097
1098static int qeth_setup_card(struct qeth_card *card)
1099{
1100
1101 QETH_DBF_TEXT(setup, 2, "setupcrd");
1102 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
1103
1104 card->read.state = CH_STATE_DOWN;
1105 card->write.state = CH_STATE_DOWN;
1106 card->data.state = CH_STATE_DOWN;
1107 card->state = CARD_STATE_DOWN;
1108 card->lan_online = 0;
1109 card->use_hard_stop = 0;
1110 card->dev = NULL;
1111 spin_lock_init(&card->vlanlock);
1112 spin_lock_init(&card->mclock);
1113 card->vlangrp = NULL;
1114 spin_lock_init(&card->lock);
1115 spin_lock_init(&card->ip_lock);
1116 spin_lock_init(&card->thread_mask_lock);
1117 card->thread_start_mask = 0;
1118 card->thread_allowed_mask = 0;
1119 card->thread_running_mask = 0;
1120 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
1121 INIT_LIST_HEAD(&card->ip_list);
1122 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1123 if (!card->ip_tbd_list) {
1124 QETH_DBF_TEXT(setup, 0, "iptbdnom");
1125 return -ENOMEM;
1126 }
1127 INIT_LIST_HEAD(card->ip_tbd_list);
1128 INIT_LIST_HEAD(&card->cmd_waiter_list);
1129 init_waitqueue_head(&card->wait_q);
1130 /* intial options */
1131 qeth_set_intial_options(card);
1132 /* IP address takeover */
1133 INIT_LIST_HEAD(&card->ipato.entries);
1134 card->ipato.enabled = 0;
1135 card->ipato.invert4 = 0;
1136 card->ipato.invert6 = 0;
1137 /* init QDIO stuff */
1138 qeth_init_qdio_info(card);
1139 return 0;
1140}
1141
1142static struct qeth_card *qeth_alloc_card(void)
1143{
1144 struct qeth_card *card;
1145
1146 QETH_DBF_TEXT(setup, 2, "alloccrd");
1147 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
1148 if (!card)
1149 return NULL;
1150 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
1151 if (qeth_setup_channel(&card->read)) {
1152 kfree(card);
1153 return NULL;
1154 }
1155 if (qeth_setup_channel(&card->write)) {
1156 qeth_clean_channel(&card->read);
1157 kfree(card);
1158 return NULL;
1159 }
1160 card->options.layer2 = -1;
1161 return card;
1162}
1163
1164static int qeth_determine_card_type(struct qeth_card *card)
1165{
1166 int i = 0;
1167
1168 QETH_DBF_TEXT(setup, 2, "detcdtyp");
1169
1170 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
1171 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
1172 while (known_devices[i][4]) {
1173 if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
1174 (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
1175 card->info.type = known_devices[i][4];
1176 card->qdio.no_out_queues = known_devices[i][8];
1177 card->info.is_multicast_different = known_devices[i][9];
1178 if (qeth_is_1920_device(card)) {
1179 PRINT_INFO("Priority Queueing not able "
1180 "due to hardware limitations!\n");
1181 card->qdio.no_out_queues = 1;
1182 card->qdio.default_out_queue = 0;
1183 }
1184 return 0;
1185 }
1186 i++;
1187 }
1188 card->info.type = QETH_CARD_TYPE_UNKNOWN;
1189 PRINT_ERR("unknown card type on device %s\n", CARD_BUS_ID(card));
1190 return -ENOENT;
1191}
1192
1193static int qeth_clear_channel(struct qeth_channel *channel)
1194{
1195 unsigned long flags;
1196 struct qeth_card *card;
1197 int rc;
1198
1199 QETH_DBF_TEXT(trace, 3, "clearch");
1200 card = CARD_FROM_CDEV(channel->ccwdev);
1201 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1202 rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM);
1203 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1204
1205 if (rc)
1206 return rc;
1207 rc = wait_event_interruptible_timeout(card->wait_q,
1208 channel->state == CH_STATE_STOPPED, QETH_TIMEOUT);
1209 if (rc == -ERESTARTSYS)
1210 return rc;
1211 if (channel->state != CH_STATE_STOPPED)
1212 return -ETIME;
1213 channel->state = CH_STATE_DOWN;
1214 return 0;
1215}
1216
1217static int qeth_halt_channel(struct qeth_channel *channel)
1218{
1219 unsigned long flags;
1220 struct qeth_card *card;
1221 int rc;
1222
1223 QETH_DBF_TEXT(trace, 3, "haltch");
1224 card = CARD_FROM_CDEV(channel->ccwdev);
1225 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1226 rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM);
1227 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1228
1229 if (rc)
1230 return rc;
1231 rc = wait_event_interruptible_timeout(card->wait_q,
1232 channel->state == CH_STATE_HALTED, QETH_TIMEOUT);
1233 if (rc == -ERESTARTSYS)
1234 return rc;
1235 if (channel->state != CH_STATE_HALTED)
1236 return -ETIME;
1237 return 0;
1238}
1239
1240static int qeth_halt_channels(struct qeth_card *card)
1241{
1242 int rc1 = 0, rc2 = 0, rc3 = 0;
1243
1244 QETH_DBF_TEXT(trace, 3, "haltchs");
1245 rc1 = qeth_halt_channel(&card->read);
1246 rc2 = qeth_halt_channel(&card->write);
1247 rc3 = qeth_halt_channel(&card->data);
1248 if (rc1)
1249 return rc1;
1250 if (rc2)
1251 return rc2;
1252 return rc3;
1253}
1254
1255static int qeth_clear_channels(struct qeth_card *card)
1256{
1257 int rc1 = 0, rc2 = 0, rc3 = 0;
1258
1259 QETH_DBF_TEXT(trace, 3, "clearchs");
1260 rc1 = qeth_clear_channel(&card->read);
1261 rc2 = qeth_clear_channel(&card->write);
1262 rc3 = qeth_clear_channel(&card->data);
1263 if (rc1)
1264 return rc1;
1265 if (rc2)
1266 return rc2;
1267 return rc3;
1268}
1269
1270static int qeth_clear_halt_card(struct qeth_card *card, int halt)
1271{
1272 int rc = 0;
1273
1274 QETH_DBF_TEXT(trace, 3, "clhacrd");
1275 QETH_DBF_HEX(trace, 3, &card, sizeof(void *));
1276
1277 if (halt)
1278 rc = qeth_halt_channels(card);
1279 if (rc)
1280 return rc;
1281 return qeth_clear_channels(card);
1282}
1283
1284int qeth_qdio_clear_card(struct qeth_card *card, int use_halt)
1285{
1286 int rc = 0;
1287
1288 QETH_DBF_TEXT(trace, 3, "qdioclr");
1289 switch (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ESTABLISHED,
1290 QETH_QDIO_CLEANING)) {
1291 case QETH_QDIO_ESTABLISHED:
1292 if (card->info.type == QETH_CARD_TYPE_IQD)
1293 rc = qdio_cleanup(CARD_DDEV(card),
1294 QDIO_FLAG_CLEANUP_USING_HALT);
1295 else
1296 rc = qdio_cleanup(CARD_DDEV(card),
1297 QDIO_FLAG_CLEANUP_USING_CLEAR);
1298 if (rc)
1299 QETH_DBF_TEXT_(trace, 3, "1err%d", rc);
1300 atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
1301 break;
1302 case QETH_QDIO_CLEANING:
1303 return rc;
1304 default:
1305 break;
1306 }
1307 rc = qeth_clear_halt_card(card, use_halt);
1308 if (rc)
1309 QETH_DBF_TEXT_(trace, 3, "2err%d", rc);
1310 card->state = CARD_STATE_DOWN;
1311 return rc;
1312}
1313EXPORT_SYMBOL_GPL(qeth_qdio_clear_card);
1314
1315static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
1316 int *length)
1317{
1318 struct ciw *ciw;
1319 char *rcd_buf;
1320 int ret;
1321 struct qeth_channel *channel = &card->data;
1322 unsigned long flags;
1323
1324 /*
1325 * scan for RCD command in extended SenseID data
1326 */
1327 ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD);
1328 if (!ciw || ciw->cmd == 0)
1329 return -EOPNOTSUPP;
1330 rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
1331 if (!rcd_buf)
1332 return -ENOMEM;
1333
1334 channel->ccw.cmd_code = ciw->cmd;
1335 channel->ccw.cda = (__u32) __pa(rcd_buf);
1336 channel->ccw.count = ciw->count;
1337 channel->ccw.flags = CCW_FLAG_SLI;
1338 channel->state = CH_STATE_RCD;
1339 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1340 ret = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
1341 QETH_RCD_PARM, LPM_ANYPATH, 0,
1342 QETH_RCD_TIMEOUT);
1343 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1344 if (!ret)
1345 wait_event(card->wait_q,
1346 (channel->state == CH_STATE_RCD_DONE ||
1347 channel->state == CH_STATE_DOWN));
1348 if (channel->state == CH_STATE_DOWN)
1349 ret = -EIO;
1350 else
1351 channel->state = CH_STATE_DOWN;
1352 if (ret) {
1353 kfree(rcd_buf);
1354 *buffer = NULL;
1355 *length = 0;
1356 } else {
1357 *length = ciw->count;
1358 *buffer = rcd_buf;
1359 }
1360 return ret;
1361}
1362
1363static int qeth_get_unitaddr(struct qeth_card *card)
1364{
1365 int length;
1366 char *prcd;
1367 int rc;
1368
1369 QETH_DBF_TEXT(setup, 2, "getunit");
1370 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
1371 if (rc) {
1372 PRINT_ERR("qeth_read_conf_data for device %s returned %i\n",
1373 CARD_DDEV_ID(card), rc);
1374 return rc;
1375 }
1376 card->info.chpid = prcd[30];
1377 card->info.unit_addr2 = prcd[31];
1378 card->info.cula = prcd[63];
1379 card->info.guestlan = ((prcd[0x10] == _ascebc['V']) &&
1380 (prcd[0x11] == _ascebc['M']));
1381 kfree(prcd);
1382 return 0;
1383}
1384
1385static void qeth_init_tokens(struct qeth_card *card)
1386{
1387 card->token.issuer_rm_w = 0x00010103UL;
1388 card->token.cm_filter_w = 0x00010108UL;
1389 card->token.cm_connection_w = 0x0001010aUL;
1390 card->token.ulp_filter_w = 0x0001010bUL;
1391 card->token.ulp_connection_w = 0x0001010dUL;
1392}
1393
1394static void qeth_init_func_level(struct qeth_card *card)
1395{
1396 if (card->ipato.enabled) {
1397 if (card->info.type == QETH_CARD_TYPE_IQD)
1398 card->info.func_level =
1399 QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT;
1400 else
1401 card->info.func_level =
1402 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
1403 } else {
1404 if (card->info.type == QETH_CARD_TYPE_IQD)
1405 /*FIXME:why do we have same values for dis and ena for
1406 osae??? */
1407 card->info.func_level =
1408 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
1409 else
1410 card->info.func_level =
1411 QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT;
1412 }
1413}
1414
1415static inline __u16 qeth_raw_devno_from_bus_id(char *id)
1416{
1417 id += (strlen(id) - 4);
1418 return (__u16) simple_strtoul(id, &id, 16);
1419}
1420
1421static int qeth_idx_activate_get_answer(struct qeth_channel *channel,
1422 void (*idx_reply_cb)(struct qeth_channel *,
1423 struct qeth_cmd_buffer *))
1424{
1425 struct qeth_cmd_buffer *iob;
1426 unsigned long flags;
1427 int rc;
1428 struct qeth_card *card;
1429
1430 QETH_DBF_TEXT(setup, 2, "idxanswr");
1431 card = CARD_FROM_CDEV(channel->ccwdev);
1432 iob = qeth_get_buffer(channel);
1433 iob->callback = idx_reply_cb;
1434 memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1));
1435 channel->ccw.count = QETH_BUFSIZE;
1436 channel->ccw.cda = (__u32) __pa(iob->data);
1437
1438 wait_event(card->wait_q,
1439 atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
1440 QETH_DBF_TEXT(setup, 6, "noirqpnd");
1441 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1442 rc = ccw_device_start(channel->ccwdev,
1443 &channel->ccw, (addr_t) iob, 0, 0);
1444 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1445
1446 if (rc) {
1447 PRINT_ERR("Error2 in activating channel rc=%d\n", rc);
1448 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
1449 atomic_set(&channel->irq_pending, 0);
1450 wake_up(&card->wait_q);
1451 return rc;
1452 }
1453 rc = wait_event_interruptible_timeout(card->wait_q,
1454 channel->state == CH_STATE_UP, QETH_TIMEOUT);
1455 if (rc == -ERESTARTSYS)
1456 return rc;
1457 if (channel->state != CH_STATE_UP) {
1458 rc = -ETIME;
1459 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
1460 qeth_clear_cmd_buffers(channel);
1461 } else
1462 rc = 0;
1463 return rc;
1464}
1465
1466static int qeth_idx_activate_channel(struct qeth_channel *channel,
1467 void (*idx_reply_cb)(struct qeth_channel *,
1468 struct qeth_cmd_buffer *))
1469{
1470 struct qeth_card *card;
1471 struct qeth_cmd_buffer *iob;
1472 unsigned long flags;
1473 __u16 temp;
1474 __u8 tmp;
1475 int rc;
1476
1477 card = CARD_FROM_CDEV(channel->ccwdev);
1478
1479 QETH_DBF_TEXT(setup, 2, "idxactch");
1480
1481 iob = qeth_get_buffer(channel);
1482 iob->callback = idx_reply_cb;
1483 memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1));
1484 channel->ccw.count = IDX_ACTIVATE_SIZE;
1485 channel->ccw.cda = (__u32) __pa(iob->data);
1486 if (channel == &card->write) {
1487 memcpy(iob->data, IDX_ACTIVATE_WRITE, IDX_ACTIVATE_SIZE);
1488 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1489 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1490 card->seqno.trans_hdr++;
1491 } else {
1492 memcpy(iob->data, IDX_ACTIVATE_READ, IDX_ACTIVATE_SIZE);
1493 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1494 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1495 }
1496 tmp = ((__u8)card->info.portno) | 0x80;
1497 memcpy(QETH_IDX_ACT_PNO(iob->data), &tmp, 1);
1498 memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
1499 &card->token.issuer_rm_w, QETH_MPC_TOKEN_LENGTH);
1500 memcpy(QETH_IDX_ACT_FUNC_LEVEL(iob->data),
1501 &card->info.func_level, sizeof(__u16));
1502 temp = qeth_raw_devno_from_bus_id(CARD_DDEV_ID(card));
1503 memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &temp, 2);
1504 temp = (card->info.cula << 8) + card->info.unit_addr2;
1505 memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &temp, 2);
1506
1507 wait_event(card->wait_q,
1508 atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
1509 QETH_DBF_TEXT(setup, 6, "noirqpnd");
1510 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1511 rc = ccw_device_start(channel->ccwdev,
1512 &channel->ccw, (addr_t) iob, 0, 0);
1513 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1514
1515 if (rc) {
1516 PRINT_ERR("Error1 in activating channel. rc=%d\n", rc);
1517 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
1518 atomic_set(&channel->irq_pending, 0);
1519 wake_up(&card->wait_q);
1520 return rc;
1521 }
1522 rc = wait_event_interruptible_timeout(card->wait_q,
1523 channel->state == CH_STATE_ACTIVATING, QETH_TIMEOUT);
1524 if (rc == -ERESTARTSYS)
1525 return rc;
1526 if (channel->state != CH_STATE_ACTIVATING) {
1527 PRINT_WARN("IDX activate timed out!\n");
1528 QETH_DBF_TEXT_(setup, 2, "2err%d", -ETIME);
1529 qeth_clear_cmd_buffers(channel);
1530 return -ETIME;
1531 }
1532 return qeth_idx_activate_get_answer(channel, idx_reply_cb);
1533}
1534
1535static int qeth_peer_func_level(int level)
1536{
1537 if ((level & 0xff) == 8)
1538 return (level & 0xff) + 0x400;
1539 if (((level >> 8) & 3) == 1)
1540 return (level & 0xff) + 0x200;
1541 return level;
1542}
1543
1544static void qeth_idx_write_cb(struct qeth_channel *channel,
1545 struct qeth_cmd_buffer *iob)
1546{
1547 struct qeth_card *card;
1548 __u16 temp;
1549
1550 QETH_DBF_TEXT(setup , 2, "idxwrcb");
1551
1552 if (channel->state == CH_STATE_DOWN) {
1553 channel->state = CH_STATE_ACTIVATING;
1554 goto out;
1555 }
1556 card = CARD_FROM_CDEV(channel->ccwdev);
1557
1558 if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
1559 if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
1560 PRINT_ERR("IDX_ACTIVATE on write channel device %s: "
1561 "adapter exclusively used by another host\n",
1562 CARD_WDEV_ID(card));
1563 else
1564 PRINT_ERR("IDX_ACTIVATE on write channel device %s: "
1565 "negative reply\n", CARD_WDEV_ID(card));
1566 goto out;
1567 }
1568 memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
1569 if ((temp & ~0x0100) != qeth_peer_func_level(card->info.func_level)) {
1570 PRINT_WARN("IDX_ACTIVATE on write channel device %s: "
1571 "function level mismatch "
1572 "(sent: 0x%x, received: 0x%x)\n",
1573 CARD_WDEV_ID(card), card->info.func_level, temp);
1574 goto out;
1575 }
1576 channel->state = CH_STATE_UP;
1577out:
1578 qeth_release_buffer(channel, iob);
1579}
1580
1581static void qeth_idx_read_cb(struct qeth_channel *channel,
1582 struct qeth_cmd_buffer *iob)
1583{
1584 struct qeth_card *card;
1585 __u16 temp;
1586
1587 QETH_DBF_TEXT(setup , 2, "idxrdcb");
1588 if (channel->state == CH_STATE_DOWN) {
1589 channel->state = CH_STATE_ACTIVATING;
1590 goto out;
1591 }
1592
1593 card = CARD_FROM_CDEV(channel->ccwdev);
1594 if (qeth_check_idx_response(iob->data))
1595 goto out;
1596
1597 if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
1598 if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
1599 PRINT_ERR("IDX_ACTIVATE on read channel device %s: "
1600 "adapter exclusively used by another host\n",
1601 CARD_RDEV_ID(card));
1602 else
1603 PRINT_ERR("IDX_ACTIVATE on read channel device %s: "
1604 "negative reply\n", CARD_RDEV_ID(card));
1605 goto out;
1606 }
1607
1608/**
1609 * temporary fix for microcode bug
1610 * to revert it,replace OR by AND
1611 */
1612 if ((!QETH_IDX_NO_PORTNAME_REQUIRED(iob->data)) ||
1613 (card->info.type == QETH_CARD_TYPE_OSAE))
1614 card->info.portname_required = 1;
1615
1616 memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
1617 if (temp != qeth_peer_func_level(card->info.func_level)) {
1618 PRINT_WARN("IDX_ACTIVATE on read channel device %s: function "
1619 "level mismatch (sent: 0x%x, received: 0x%x)\n",
1620 CARD_RDEV_ID(card), card->info.func_level, temp);
1621 goto out;
1622 }
1623 memcpy(&card->token.issuer_rm_r,
1624 QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
1625 QETH_MPC_TOKEN_LENGTH);
1626 memcpy(&card->info.mcl_level[0],
1627 QETH_IDX_REPLY_LEVEL(iob->data), QETH_MCL_LENGTH);
1628 channel->state = CH_STATE_UP;
1629out:
1630 qeth_release_buffer(channel, iob);
1631}
1632
1633void qeth_prepare_control_data(struct qeth_card *card, int len,
1634 struct qeth_cmd_buffer *iob)
1635{
1636 qeth_setup_ccw(&card->write, iob->data, len);
1637 iob->callback = qeth_release_buffer;
1638
1639 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1640 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1641 card->seqno.trans_hdr++;
1642 memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
1643 &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
1644 card->seqno.pdu_hdr++;
1645 memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
1646 &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
1647 QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
1648}
1649EXPORT_SYMBOL_GPL(qeth_prepare_control_data);
1650
1651int qeth_send_control_data(struct qeth_card *card, int len,
1652 struct qeth_cmd_buffer *iob,
1653 int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
1654 unsigned long),
1655 void *reply_param)
1656{
1657 int rc;
1658 unsigned long flags;
1659 struct qeth_reply *reply = NULL;
1660 unsigned long timeout;
1661
1662 QETH_DBF_TEXT(trace, 2, "sendctl");
1663
1664 reply = qeth_alloc_reply(card);
1665 if (!reply) {
1666 PRINT_WARN("Could no alloc qeth_reply!\n");
1667 return -ENOMEM;
1668 }
1669 reply->callback = reply_cb;
1670 reply->param = reply_param;
1671 if (card->state == CARD_STATE_DOWN)
1672 reply->seqno = QETH_IDX_COMMAND_SEQNO;
1673 else
1674 reply->seqno = card->seqno.ipa++;
1675 init_waitqueue_head(&reply->wait_q);
1676 spin_lock_irqsave(&card->lock, flags);
1677 list_add_tail(&reply->list, &card->cmd_waiter_list);
1678 spin_unlock_irqrestore(&card->lock, flags);
1679 QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
1680
1681 while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
1682 qeth_prepare_control_data(card, len, iob);
1683
1684 if (IS_IPA(iob->data))
1685 timeout = jiffies + QETH_IPA_TIMEOUT;
1686 else
1687 timeout = jiffies + QETH_TIMEOUT;
1688
1689 QETH_DBF_TEXT(trace, 6, "noirqpnd");
1690 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
1691 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
1692 (addr_t) iob, 0, 0);
1693 spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
1694 if (rc) {
1695 PRINT_WARN("qeth_send_control_data: "
1696 "ccw_device_start rc = %i\n", rc);
1697 QETH_DBF_TEXT_(trace, 2, " err%d", rc);
1698 spin_lock_irqsave(&card->lock, flags);
1699 list_del_init(&reply->list);
1700 qeth_put_reply(reply);
1701 spin_unlock_irqrestore(&card->lock, flags);
1702 qeth_release_buffer(iob->channel, iob);
1703 atomic_set(&card->write.irq_pending, 0);
1704 wake_up(&card->wait_q);
1705 return rc;
1706 }
1707 while (!atomic_read(&reply->received)) {
1708 if (time_after(jiffies, timeout)) {
1709 spin_lock_irqsave(&reply->card->lock, flags);
1710 list_del_init(&reply->list);
1711 spin_unlock_irqrestore(&reply->card->lock, flags);
1712 reply->rc = -ETIME;
1713 atomic_inc(&reply->received);
1714 wake_up(&reply->wait_q);
1715 }
1716 cpu_relax();
1717 };
1718 rc = reply->rc;
1719 qeth_put_reply(reply);
1720 return rc;
1721}
1722EXPORT_SYMBOL_GPL(qeth_send_control_data);
1723
1724static int qeth_cm_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
1725 unsigned long data)
1726{
1727 struct qeth_cmd_buffer *iob;
1728
1729 QETH_DBF_TEXT(setup, 2, "cmenblcb");
1730
1731 iob = (struct qeth_cmd_buffer *) data;
1732 memcpy(&card->token.cm_filter_r,
1733 QETH_CM_ENABLE_RESP_FILTER_TOKEN(iob->data),
1734 QETH_MPC_TOKEN_LENGTH);
1735 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
1736 return 0;
1737}
1738
1739static int qeth_cm_enable(struct qeth_card *card)
1740{
1741 int rc;
1742 struct qeth_cmd_buffer *iob;
1743
1744 QETH_DBF_TEXT(setup, 2, "cmenable");
1745
1746 iob = qeth_wait_for_buffer(&card->write);
1747 memcpy(iob->data, CM_ENABLE, CM_ENABLE_SIZE);
1748 memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(iob->data),
1749 &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
1750 memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data),
1751 &card->token.cm_filter_w, QETH_MPC_TOKEN_LENGTH);
1752
1753 rc = qeth_send_control_data(card, CM_ENABLE_SIZE, iob,
1754 qeth_cm_enable_cb, NULL);
1755 return rc;
1756}
1757
1758static int qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
1759 unsigned long data)
1760{
1761
1762 struct qeth_cmd_buffer *iob;
1763
1764 QETH_DBF_TEXT(setup, 2, "cmsetpcb");
1765
1766 iob = (struct qeth_cmd_buffer *) data;
1767 memcpy(&card->token.cm_connection_r,
1768 QETH_CM_SETUP_RESP_DEST_ADDR(iob->data),
1769 QETH_MPC_TOKEN_LENGTH);
1770 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
1771 return 0;
1772}
1773
1774static int qeth_cm_setup(struct qeth_card *card)
1775{
1776 int rc;
1777 struct qeth_cmd_buffer *iob;
1778
1779 QETH_DBF_TEXT(setup, 2, "cmsetup");
1780
1781 iob = qeth_wait_for_buffer(&card->write);
1782 memcpy(iob->data, CM_SETUP, CM_SETUP_SIZE);
1783 memcpy(QETH_CM_SETUP_DEST_ADDR(iob->data),
1784 &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
1785 memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(iob->data),
1786 &card->token.cm_connection_w, QETH_MPC_TOKEN_LENGTH);
1787 memcpy(QETH_CM_SETUP_FILTER_TOKEN(iob->data),
1788 &card->token.cm_filter_r, QETH_MPC_TOKEN_LENGTH);
1789 rc = qeth_send_control_data(card, CM_SETUP_SIZE, iob,
1790 qeth_cm_setup_cb, NULL);
1791 return rc;
1792
1793}
1794
1795static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card)
1796{
1797 switch (card->info.type) {
1798 case QETH_CARD_TYPE_UNKNOWN:
1799 return 1500;
1800 case QETH_CARD_TYPE_IQD:
1801 return card->info.max_mtu;
1802 case QETH_CARD_TYPE_OSAE:
1803 switch (card->info.link_type) {
1804 case QETH_LINK_TYPE_HSTR:
1805 case QETH_LINK_TYPE_LANE_TR:
1806 return 2000;
1807 default:
1808 return 1492;
1809 }
1810 default:
1811 return 1500;
1812 }
1813}
1814
1815static inline int qeth_get_max_mtu_for_card(int cardtype)
1816{
1817 switch (cardtype) {
1818
1819 case QETH_CARD_TYPE_UNKNOWN:
1820 case QETH_CARD_TYPE_OSAE:
1821 case QETH_CARD_TYPE_OSN:
1822 return 61440;
1823 case QETH_CARD_TYPE_IQD:
1824 return 57344;
1825 default:
1826 return 1500;
1827 }
1828}
1829
1830static inline int qeth_get_mtu_out_of_mpc(int cardtype)
1831{
1832 switch (cardtype) {
1833 case QETH_CARD_TYPE_IQD:
1834 return 1;
1835 default:
1836 return 0;
1837 }
1838}
1839
1840static inline int qeth_get_mtu_outof_framesize(int framesize)
1841{
1842 switch (framesize) {
1843 case 0x4000:
1844 return 8192;
1845 case 0x6000:
1846 return 16384;
1847 case 0xa000:
1848 return 32768;
1849 case 0xffff:
1850 return 57344;
1851 default:
1852 return 0;
1853 }
1854}
1855
1856static inline int qeth_mtu_is_valid(struct qeth_card *card, int mtu)
1857{
1858 switch (card->info.type) {
1859 case QETH_CARD_TYPE_OSAE:
1860 return ((mtu >= 576) && (mtu <= 61440));
1861 case QETH_CARD_TYPE_IQD:
1862 return ((mtu >= 576) &&
1863 (mtu <= card->info.max_mtu + 4096 - 32));
1864 case QETH_CARD_TYPE_OSN:
1865 case QETH_CARD_TYPE_UNKNOWN:
1866 default:
1867 return 1;
1868 }
1869}
1870
1871static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
1872 unsigned long data)
1873{
1874
1875 __u16 mtu, framesize;
1876 __u16 len;
1877 __u8 link_type;
1878 struct qeth_cmd_buffer *iob;
1879
1880 QETH_DBF_TEXT(setup, 2, "ulpenacb");
1881
1882 iob = (struct qeth_cmd_buffer *) data;
1883 memcpy(&card->token.ulp_filter_r,
1884 QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data),
1885 QETH_MPC_TOKEN_LENGTH);
1886 if (qeth_get_mtu_out_of_mpc(card->info.type)) {
1887 memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2);
1888 mtu = qeth_get_mtu_outof_framesize(framesize);
1889 if (!mtu) {
1890 iob->rc = -EINVAL;
1891 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
1892 return 0;
1893 }
1894 card->info.max_mtu = mtu;
1895 card->info.initial_mtu = mtu;
1896 card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE;
1897 } else {
1898 card->info.initial_mtu = qeth_get_initial_mtu_for_card(card);
1899 card->info.max_mtu = qeth_get_max_mtu_for_card(card->info.type);
1900 card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
1901 }
1902
1903 memcpy(&len, QETH_ULP_ENABLE_RESP_DIFINFO_LEN(iob->data), 2);
1904 if (len >= QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
1905 memcpy(&link_type,
1906 QETH_ULP_ENABLE_RESP_LINK_TYPE(iob->data), 1);
1907 card->info.link_type = link_type;
1908 } else
1909 card->info.link_type = 0;
1910 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
1911 return 0;
1912}
1913
1914static int qeth_ulp_enable(struct qeth_card *card)
1915{
1916 int rc;
1917 char prot_type;
1918 struct qeth_cmd_buffer *iob;
1919
1920 /*FIXME: trace view callbacks*/
1921 QETH_DBF_TEXT(setup, 2, "ulpenabl");
1922
1923 iob = qeth_wait_for_buffer(&card->write);
1924 memcpy(iob->data, ULP_ENABLE, ULP_ENABLE_SIZE);
1925
1926 *(QETH_ULP_ENABLE_LINKNUM(iob->data)) =
1927 (__u8) card->info.portno;
1928 if (card->options.layer2)
1929 if (card->info.type == QETH_CARD_TYPE_OSN)
1930 prot_type = QETH_PROT_OSN2;
1931 else
1932 prot_type = QETH_PROT_LAYER2;
1933 else
1934 prot_type = QETH_PROT_TCPIP;
1935
1936 memcpy(QETH_ULP_ENABLE_PROT_TYPE(iob->data), &prot_type, 1);
1937 memcpy(QETH_ULP_ENABLE_DEST_ADDR(iob->data),
1938 &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
1939 memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data),
1940 &card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH);
1941 memcpy(QETH_ULP_ENABLE_PORTNAME_AND_LL(iob->data),
1942 card->info.portname, 9);
1943 rc = qeth_send_control_data(card, ULP_ENABLE_SIZE, iob,
1944 qeth_ulp_enable_cb, NULL);
1945 return rc;
1946
1947}
1948
1949static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
1950 unsigned long data)
1951{
1952 struct qeth_cmd_buffer *iob;
1953
1954 QETH_DBF_TEXT(setup, 2, "ulpstpcb");
1955
1956 iob = (struct qeth_cmd_buffer *) data;
1957 memcpy(&card->token.ulp_connection_r,
1958 QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data),
1959 QETH_MPC_TOKEN_LENGTH);
1960 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
1961 return 0;
1962}
1963
1964static int qeth_ulp_setup(struct qeth_card *card)
1965{
1966 int rc;
1967 __u16 temp;
1968 struct qeth_cmd_buffer *iob;
1969 struct ccw_dev_id dev_id;
1970
1971 QETH_DBF_TEXT(setup, 2, "ulpsetup");
1972
1973 iob = qeth_wait_for_buffer(&card->write);
1974 memcpy(iob->data, ULP_SETUP, ULP_SETUP_SIZE);
1975
1976 memcpy(QETH_ULP_SETUP_DEST_ADDR(iob->data),
1977 &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
1978 memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(iob->data),
1979 &card->token.ulp_connection_w, QETH_MPC_TOKEN_LENGTH);
1980 memcpy(QETH_ULP_SETUP_FILTER_TOKEN(iob->data),
1981 &card->token.ulp_filter_r, QETH_MPC_TOKEN_LENGTH);
1982
1983 ccw_device_get_id(CARD_DDEV(card), &dev_id);
1984 memcpy(QETH_ULP_SETUP_CUA(iob->data), &dev_id.devno, 2);
1985 temp = (card->info.cula << 8) + card->info.unit_addr2;
1986 memcpy(QETH_ULP_SETUP_REAL_DEVADDR(iob->data), &temp, 2);
1987 rc = qeth_send_control_data(card, ULP_SETUP_SIZE, iob,
1988 qeth_ulp_setup_cb, NULL);
1989 return rc;
1990}
1991
1992static int qeth_alloc_qdio_buffers(struct qeth_card *card)
1993{
1994 int i, j;
1995
1996 QETH_DBF_TEXT(setup, 2, "allcqdbf");
1997
1998 if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED,
1999 QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
2000 return 0;
2001
2002 card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
2003 GFP_KERNEL|GFP_DMA);
2004 if (!card->qdio.in_q)
2005 goto out_nomem;
2006 QETH_DBF_TEXT(setup, 2, "inq");
2007 QETH_DBF_HEX(setup, 2, &card->qdio.in_q, sizeof(void *));
2008 memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q));
2009 /* give inbound qeth_qdio_buffers their qdio_buffers */
2010 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
2011 card->qdio.in_q->bufs[i].buffer =
2012 &card->qdio.in_q->qdio_bufs[i];
2013 /* inbound buffer pool */
2014 if (qeth_alloc_buffer_pool(card))
2015 goto out_freeinq;
2016 /* outbound */
2017 card->qdio.out_qs =
2018 kmalloc(card->qdio.no_out_queues *
2019 sizeof(struct qeth_qdio_out_q *), GFP_KERNEL);
2020 if (!card->qdio.out_qs)
2021 goto out_freepool;
2022 for (i = 0; i < card->qdio.no_out_queues; ++i) {
2023 card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
2024 GFP_KERNEL|GFP_DMA);
2025 if (!card->qdio.out_qs[i])
2026 goto out_freeoutq;
2027 QETH_DBF_TEXT_(setup, 2, "outq %i", i);
2028 QETH_DBF_HEX(setup, 2, &card->qdio.out_qs[i], sizeof(void *));
2029 memset(card->qdio.out_qs[i], 0, sizeof(struct qeth_qdio_out_q));
2030 card->qdio.out_qs[i]->queue_no = i;
2031 /* give outbound qeth_qdio_buffers their qdio_buffers */
2032 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
2033 card->qdio.out_qs[i]->bufs[j].buffer =
2034 &card->qdio.out_qs[i]->qdio_bufs[j];
2035 skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j].
2036 skb_list);
2037 lockdep_set_class(
2038 &card->qdio.out_qs[i]->bufs[j].skb_list.lock,
2039 &qdio_out_skb_queue_key);
2040 INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list);
2041 }
2042 }
2043 return 0;
2044
2045out_freeoutq:
2046 while (i > 0)
2047 kfree(card->qdio.out_qs[--i]);
2048 kfree(card->qdio.out_qs);
2049 card->qdio.out_qs = NULL;
2050out_freepool:
2051 qeth_free_buffer_pool(card);
2052out_freeinq:
2053 kfree(card->qdio.in_q);
2054 card->qdio.in_q = NULL;
2055out_nomem:
2056 atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
2057 return -ENOMEM;
2058}
2059
2060static void qeth_create_qib_param_field(struct qeth_card *card,
2061 char *param_field)
2062{
2063
2064 param_field[0] = _ascebc['P'];
2065 param_field[1] = _ascebc['C'];
2066 param_field[2] = _ascebc['I'];
2067 param_field[3] = _ascebc['T'];
2068 *((unsigned int *) (&param_field[4])) = QETH_PCI_THRESHOLD_A(card);
2069 *((unsigned int *) (&param_field[8])) = QETH_PCI_THRESHOLD_B(card);
2070 *((unsigned int *) (&param_field[12])) = QETH_PCI_TIMER_VALUE(card);
2071}
2072
2073static void qeth_create_qib_param_field_blkt(struct qeth_card *card,
2074 char *param_field)
2075{
2076 param_field[16] = _ascebc['B'];
2077 param_field[17] = _ascebc['L'];
2078 param_field[18] = _ascebc['K'];
2079 param_field[19] = _ascebc['T'];
2080 *((unsigned int *) (&param_field[20])) = card->info.blkt.time_total;
2081 *((unsigned int *) (&param_field[24])) = card->info.blkt.inter_packet;
2082 *((unsigned int *) (&param_field[28])) =
2083 card->info.blkt.inter_packet_jumbo;
2084}
2085
2086static int qeth_qdio_activate(struct qeth_card *card)
2087{
2088 QETH_DBF_TEXT(setup, 3, "qdioact");
2089 return qdio_activate(CARD_DDEV(card), 0);
2090}
2091
2092static int qeth_dm_act(struct qeth_card *card)
2093{
2094 int rc;
2095 struct qeth_cmd_buffer *iob;
2096
2097 QETH_DBF_TEXT(setup, 2, "dmact");
2098
2099 iob = qeth_wait_for_buffer(&card->write);
2100 memcpy(iob->data, DM_ACT, DM_ACT_SIZE);
2101
2102 memcpy(QETH_DM_ACT_DEST_ADDR(iob->data),
2103 &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
2104 memcpy(QETH_DM_ACT_CONNECTION_TOKEN(iob->data),
2105 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
2106 rc = qeth_send_control_data(card, DM_ACT_SIZE, iob, NULL, NULL);
2107 return rc;
2108}
2109
2110static int qeth_mpc_initialize(struct qeth_card *card)
2111{
2112 int rc;
2113
2114 QETH_DBF_TEXT(setup, 2, "mpcinit");
2115
2116 rc = qeth_issue_next_read(card);
2117 if (rc) {
2118 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
2119 return rc;
2120 }
2121 rc = qeth_cm_enable(card);
2122 if (rc) {
2123 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
2124 goto out_qdio;
2125 }
2126 rc = qeth_cm_setup(card);
2127 if (rc) {
2128 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
2129 goto out_qdio;
2130 }
2131 rc = qeth_ulp_enable(card);
2132 if (rc) {
2133 QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
2134 goto out_qdio;
2135 }
2136 rc = qeth_ulp_setup(card);
2137 if (rc) {
2138 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
2139 goto out_qdio;
2140 }
2141 rc = qeth_alloc_qdio_buffers(card);
2142 if (rc) {
2143 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
2144 goto out_qdio;
2145 }
2146 rc = qeth_qdio_establish(card);
2147 if (rc) {
2148 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
2149 qeth_free_qdio_buffers(card);
2150 goto out_qdio;
2151 }
2152 rc = qeth_qdio_activate(card);
2153 if (rc) {
2154 QETH_DBF_TEXT_(setup, 2, "7err%d", rc);
2155 goto out_qdio;
2156 }
2157 rc = qeth_dm_act(card);
2158 if (rc) {
2159 QETH_DBF_TEXT_(setup, 2, "8err%d", rc);
2160 goto out_qdio;
2161 }
2162
2163 return 0;
2164out_qdio:
2165 qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD);
2166 return rc;
2167}
2168
2169static void qeth_print_status_with_portname(struct qeth_card *card)
2170{
2171 char dbf_text[15];
2172 int i;
2173
2174 sprintf(dbf_text, "%s", card->info.portname + 1);
2175 for (i = 0; i < 8; i++)
2176 dbf_text[i] =
2177 (char) _ebcasc[(__u8) dbf_text[i]];
2178 dbf_text[8] = 0;
2179 PRINT_INFO("Device %s/%s/%s is a%s card%s%s%s\n"
2180 "with link type %s (portname: %s)\n",
2181 CARD_RDEV_ID(card),
2182 CARD_WDEV_ID(card),
2183 CARD_DDEV_ID(card),
2184 qeth_get_cardname(card),
2185 (card->info.mcl_level[0]) ? " (level: " : "",
2186 (card->info.mcl_level[0]) ? card->info.mcl_level : "",
2187 (card->info.mcl_level[0]) ? ")" : "",
2188 qeth_get_cardname_short(card),
2189 dbf_text);
2190
2191}
2192
2193static void qeth_print_status_no_portname(struct qeth_card *card)
2194{
2195 if (card->info.portname[0])
2196 PRINT_INFO("Device %s/%s/%s is a%s "
2197 "card%s%s%s\nwith link type %s "
2198 "(no portname needed by interface).\n",
2199 CARD_RDEV_ID(card),
2200 CARD_WDEV_ID(card),
2201 CARD_DDEV_ID(card),
2202 qeth_get_cardname(card),
2203 (card->info.mcl_level[0]) ? " (level: " : "",
2204 (card->info.mcl_level[0]) ? card->info.mcl_level : "",
2205 (card->info.mcl_level[0]) ? ")" : "",
2206 qeth_get_cardname_short(card));
2207 else
2208 PRINT_INFO("Device %s/%s/%s is a%s "
2209 "card%s%s%s\nwith link type %s.\n",
2210 CARD_RDEV_ID(card),
2211 CARD_WDEV_ID(card),
2212 CARD_DDEV_ID(card),
2213 qeth_get_cardname(card),
2214 (card->info.mcl_level[0]) ? " (level: " : "",
2215 (card->info.mcl_level[0]) ? card->info.mcl_level : "",
2216 (card->info.mcl_level[0]) ? ")" : "",
2217 qeth_get_cardname_short(card));
2218}
2219
2220void qeth_print_status_message(struct qeth_card *card)
2221{
2222 switch (card->info.type) {
2223 case QETH_CARD_TYPE_OSAE:
2224 /* VM will use a non-zero first character
2225 * to indicate a HiperSockets like reporting
2226 * of the level OSA sets the first character to zero
2227 * */
2228 if (!card->info.mcl_level[0]) {
2229 sprintf(card->info.mcl_level, "%02x%02x",
2230 card->info.mcl_level[2],
2231 card->info.mcl_level[3]);
2232
2233 card->info.mcl_level[QETH_MCL_LENGTH] = 0;
2234 break;
2235 }
2236 /* fallthrough */
2237 case QETH_CARD_TYPE_IQD:
2238 if (card->info.guestlan) {
2239 card->info.mcl_level[0] = (char) _ebcasc[(__u8)
2240 card->info.mcl_level[0]];
2241 card->info.mcl_level[1] = (char) _ebcasc[(__u8)
2242 card->info.mcl_level[1]];
2243 card->info.mcl_level[2] = (char) _ebcasc[(__u8)
2244 card->info.mcl_level[2]];
2245 card->info.mcl_level[3] = (char) _ebcasc[(__u8)
2246 card->info.mcl_level[3]];
2247 card->info.mcl_level[QETH_MCL_LENGTH] = 0;
2248 }
2249 break;
2250 default:
2251 memset(&card->info.mcl_level[0], 0, QETH_MCL_LENGTH + 1);
2252 }
2253 if (card->info.portname_required)
2254 qeth_print_status_with_portname(card);
2255 else
2256 qeth_print_status_no_portname(card);
2257}
2258EXPORT_SYMBOL_GPL(qeth_print_status_message);
2259
2260void qeth_put_buffer_pool_entry(struct qeth_card *card,
2261 struct qeth_buffer_pool_entry *entry)
2262{
2263 QETH_DBF_TEXT(trace, 6, "ptbfplen");
2264 list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
2265}
2266EXPORT_SYMBOL_GPL(qeth_put_buffer_pool_entry);
2267
2268static void qeth_initialize_working_pool_list(struct qeth_card *card)
2269{
2270 struct qeth_buffer_pool_entry *entry;
2271
2272 QETH_DBF_TEXT(trace, 5, "inwrklst");
2273
2274 list_for_each_entry(entry,
2275 &card->qdio.init_pool.entry_list, init_list) {
2276 qeth_put_buffer_pool_entry(card, entry);
2277 }
2278}
2279
2280static inline struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry(
2281 struct qeth_card *card)
2282{
2283 struct list_head *plh;
2284 struct qeth_buffer_pool_entry *entry;
2285 int i, free;
2286 struct page *page;
2287
2288 if (list_empty(&card->qdio.in_buf_pool.entry_list))
2289 return NULL;
2290
2291 list_for_each(plh, &card->qdio.in_buf_pool.entry_list) {
2292 entry = list_entry(plh, struct qeth_buffer_pool_entry, list);
2293 free = 1;
2294 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
2295 if (page_count(virt_to_page(entry->elements[i])) > 1) {
2296 free = 0;
2297 break;
2298 }
2299 }
2300 if (free) {
2301 list_del_init(&entry->list);
2302 return entry;
2303 }
2304 }
2305
2306 /* no free buffer in pool so take first one and swap pages */
2307 entry = list_entry(card->qdio.in_buf_pool.entry_list.next,
2308 struct qeth_buffer_pool_entry, list);
2309 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
2310 if (page_count(virt_to_page(entry->elements[i])) > 1) {
2311 page = alloc_page(GFP_ATOMIC|GFP_DMA);
2312 if (!page) {
2313 return NULL;
2314 } else {
2315 free_page((unsigned long)entry->elements[i]);
2316 entry->elements[i] = page_address(page);
2317 if (card->options.performance_stats)
2318 card->perf_stats.sg_alloc_page_rx++;
2319 }
2320 }
2321 }
2322 list_del_init(&entry->list);
2323 return entry;
2324}
2325
2326static int qeth_init_input_buffer(struct qeth_card *card,
2327 struct qeth_qdio_buffer *buf)
2328{
2329 struct qeth_buffer_pool_entry *pool_entry;
2330 int i;
2331
2332 pool_entry = qeth_find_free_buffer_pool_entry(card);
2333 if (!pool_entry)
2334 return 1;
2335
2336 /*
2337 * since the buffer is accessed only from the input_tasklet
2338 * there shouldn't be a need to synchronize; also, since we use
2339 * the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run out off
2340 * buffers
2341 */
2342 BUG_ON(!pool_entry);
2343
2344 buf->pool_entry = pool_entry;
2345 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
2346 buf->buffer->element[i].length = PAGE_SIZE;
2347 buf->buffer->element[i].addr = pool_entry->elements[i];
2348 if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
2349 buf->buffer->element[i].flags = SBAL_FLAGS_LAST_ENTRY;
2350 else
2351 buf->buffer->element[i].flags = 0;
2352 }
2353 return 0;
2354}
2355
2356int qeth_init_qdio_queues(struct qeth_card *card)
2357{
2358 int i, j;
2359 int rc;
2360
2361 QETH_DBF_TEXT(setup, 2, "initqdqs");
2362
2363 /* inbound queue */
2364 memset(card->qdio.in_q->qdio_bufs, 0,
2365 QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
2366 qeth_initialize_working_pool_list(card);
2367 /*give only as many buffers to hardware as we have buffer pool entries*/
2368 for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
2369 qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]);
2370 card->qdio.in_q->next_buf_to_init =
2371 card->qdio.in_buf_pool.buf_count - 1;
2372 rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0,
2373 card->qdio.in_buf_pool.buf_count - 1, NULL);
2374 if (rc) {
2375 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
2376 return rc;
2377 }
2378 rc = qdio_synchronize(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0);
2379 if (rc) {
2380 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
2381 return rc;
2382 }
2383 /* outbound queue */
2384 for (i = 0; i < card->qdio.no_out_queues; ++i) {
2385 memset(card->qdio.out_qs[i]->qdio_bufs, 0,
2386 QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
2387 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
2388 qeth_clear_output_buffer(card->qdio.out_qs[i],
2389 &card->qdio.out_qs[i]->bufs[j]);
2390 }
2391 card->qdio.out_qs[i]->card = card;
2392 card->qdio.out_qs[i]->next_buf_to_fill = 0;
2393 card->qdio.out_qs[i]->do_pack = 0;
2394 atomic_set(&card->qdio.out_qs[i]->used_buffers, 0);
2395 atomic_set(&card->qdio.out_qs[i]->set_pci_flags_count, 0);
2396 atomic_set(&card->qdio.out_qs[i]->state,
2397 QETH_OUT_Q_UNLOCKED);
2398 }
2399 return 0;
2400}
2401EXPORT_SYMBOL_GPL(qeth_init_qdio_queues);
2402
2403static inline __u8 qeth_get_ipa_adp_type(enum qeth_link_types link_type)
2404{
2405 switch (link_type) {
2406 case QETH_LINK_TYPE_HSTR:
2407 return 2;
2408 default:
2409 return 1;
2410 }
2411}
2412
2413static void qeth_fill_ipacmd_header(struct qeth_card *card,
2414 struct qeth_ipa_cmd *cmd, __u8 command,
2415 enum qeth_prot_versions prot)
2416{
2417 memset(cmd, 0, sizeof(struct qeth_ipa_cmd));
2418 cmd->hdr.command = command;
2419 cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST;
2420 cmd->hdr.seqno = card->seqno.ipa;
2421 cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type);
2422 cmd->hdr.rel_adapter_no = (__u8) card->info.portno;
2423 if (card->options.layer2)
2424 cmd->hdr.prim_version_no = 2;
2425 else
2426 cmd->hdr.prim_version_no = 1;
2427 cmd->hdr.param_count = 1;
2428 cmd->hdr.prot_version = prot;
2429 cmd->hdr.ipa_supported = 0;
2430 cmd->hdr.ipa_enabled = 0;
2431}
2432
2433struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
2434 enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot)
2435{
2436 struct qeth_cmd_buffer *iob;
2437 struct qeth_ipa_cmd *cmd;
2438
2439 iob = qeth_wait_for_buffer(&card->write);
2440 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
2441 qeth_fill_ipacmd_header(card, cmd, ipacmd, prot);
2442
2443 return iob;
2444}
2445EXPORT_SYMBOL_GPL(qeth_get_ipacmd_buffer);
2446
2447void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
2448 char prot_type)
2449{
2450 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
2451 memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data), &prot_type, 1);
2452 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
2453 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
2454}
2455EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
2456
2457int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
2458 int (*reply_cb)(struct qeth_card *, struct qeth_reply*,
2459 unsigned long),
2460 void *reply_param)
2461{
2462 int rc;
2463 char prot_type;
2464 int cmd;
2465 cmd = ((struct qeth_ipa_cmd *)
2466 (iob->data+IPA_PDU_HEADER_SIZE))->hdr.command;
2467
2468 QETH_DBF_TEXT(trace, 4, "sendipa");
2469
2470 if (card->options.layer2)
2471 if (card->info.type == QETH_CARD_TYPE_OSN)
2472 prot_type = QETH_PROT_OSN2;
2473 else
2474 prot_type = QETH_PROT_LAYER2;
2475 else
2476 prot_type = QETH_PROT_TCPIP;
2477 qeth_prepare_ipa_cmd(card, iob, prot_type);
2478 rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob,
2479 reply_cb, reply_param);
2480 if (rc != 0) {
2481 char *ipa_cmd_name;
2482 ipa_cmd_name = qeth_get_ipa_cmd_name(cmd);
2483 PRINT_ERR("%s %s(%x) returned %s(%x)\n", __FUNCTION__,
2484 ipa_cmd_name, cmd, qeth_get_ipa_msg(rc), rc);
2485 }
2486 return rc;
2487}
2488EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd);
2489
2490static int qeth_send_startstoplan(struct qeth_card *card,
2491 enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot)
2492{
2493 int rc;
2494 struct qeth_cmd_buffer *iob;
2495
2496 iob = qeth_get_ipacmd_buffer(card, ipacmd, prot);
2497 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
2498
2499 return rc;
2500}
2501
2502int qeth_send_startlan(struct qeth_card *card)
2503{
2504 int rc;
2505
2506 QETH_DBF_TEXT(setup, 2, "strtlan");
2507
2508 rc = qeth_send_startstoplan(card, IPA_CMD_STARTLAN, 0);
2509 return rc;
2510}
2511EXPORT_SYMBOL_GPL(qeth_send_startlan);
2512
2513int qeth_send_stoplan(struct qeth_card *card)
2514{
2515 int rc = 0;
2516
2517 /*
2518 * TODO: according to the IPA format document page 14,
2519 * TCP/IP (we!) never issue a STOPLAN
2520 * is this right ?!?
2521 */
2522 QETH_DBF_TEXT(setup, 2, "stoplan");
2523
2524 rc = qeth_send_startstoplan(card, IPA_CMD_STOPLAN, 0);
2525 return rc;
2526}
2527EXPORT_SYMBOL_GPL(qeth_send_stoplan);
2528
2529int qeth_default_setadapterparms_cb(struct qeth_card *card,
2530 struct qeth_reply *reply, unsigned long data)
2531{
2532 struct qeth_ipa_cmd *cmd;
2533
2534 QETH_DBF_TEXT(trace, 4, "defadpcb");
2535
2536 cmd = (struct qeth_ipa_cmd *) data;
2537 if (cmd->hdr.return_code == 0)
2538 cmd->hdr.return_code =
2539 cmd->data.setadapterparms.hdr.return_code;
2540 return 0;
2541}
2542EXPORT_SYMBOL_GPL(qeth_default_setadapterparms_cb);
2543
2544static int qeth_query_setadapterparms_cb(struct qeth_card *card,
2545 struct qeth_reply *reply, unsigned long data)
2546{
2547 struct qeth_ipa_cmd *cmd;
2548
2549 QETH_DBF_TEXT(trace, 3, "quyadpcb");
2550
2551 cmd = (struct qeth_ipa_cmd *) data;
2552 if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f)
2553 card->info.link_type =
2554 cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
2555 card->options.adp.supported_funcs =
2556 cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds;
2557 return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
2558}
2559
2560struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
2561 __u32 command, __u32 cmdlen)
2562{
2563 struct qeth_cmd_buffer *iob;
2564 struct qeth_ipa_cmd *cmd;
2565
2566 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS,
2567 QETH_PROT_IPV4);
2568 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
2569 cmd->data.setadapterparms.hdr.cmdlength = cmdlen;
2570 cmd->data.setadapterparms.hdr.command_code = command;
2571 cmd->data.setadapterparms.hdr.used_total = 1;
2572 cmd->data.setadapterparms.hdr.seq_no = 1;
2573
2574 return iob;
2575}
2576EXPORT_SYMBOL_GPL(qeth_get_adapter_cmd);
2577
2578int qeth_query_setadapterparms(struct qeth_card *card)
2579{
2580 int rc;
2581 struct qeth_cmd_buffer *iob;
2582
2583 QETH_DBF_TEXT(trace, 3, "queryadp");
2584 iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED,
2585 sizeof(struct qeth_ipacmd_setadpparms));
2586 rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL);
2587 return rc;
2588}
2589EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
2590
2591int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
2592 unsigned int siga_error, const char *dbftext)
2593{
2594 if (qdio_error || siga_error) {
2595 QETH_DBF_TEXT(trace, 2, dbftext);
2596 QETH_DBF_TEXT(qerr, 2, dbftext);
2597 QETH_DBF_TEXT_(qerr, 2, " F15=%02X",
2598 buf->element[15].flags & 0xff);
2599 QETH_DBF_TEXT_(qerr, 2, " F14=%02X",
2600 buf->element[14].flags & 0xff);
2601 QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error);
2602 QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error);
2603 return 1;
2604 }
2605 return 0;
2606}
2607EXPORT_SYMBOL_GPL(qeth_check_qdio_errors);
2608
2609void qeth_queue_input_buffer(struct qeth_card *card, int index)
2610{
2611 struct qeth_qdio_q *queue = card->qdio.in_q;
2612 int count;
2613 int i;
2614 int rc;
2615 int newcount = 0;
2616
2617 QETH_DBF_TEXT(trace, 6, "queinbuf");
2618 count = (index < queue->next_buf_to_init)?
2619 card->qdio.in_buf_pool.buf_count -
2620 (queue->next_buf_to_init - index) :
2621 card->qdio.in_buf_pool.buf_count -
2622 (queue->next_buf_to_init + QDIO_MAX_BUFFERS_PER_Q - index);
2623 /* only requeue at a certain threshold to avoid SIGAs */
2624 if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)) {
2625 for (i = queue->next_buf_to_init;
2626 i < queue->next_buf_to_init + count; ++i) {
2627 if (qeth_init_input_buffer(card,
2628 &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q])) {
2629 break;
2630 } else {
2631 newcount++;
2632 }
2633 }
2634
2635 if (newcount < count) {
2636 /* we are in memory shortage so we switch back to
2637 traditional skb allocation and drop packages */
2638 if (!atomic_read(&card->force_alloc_skb) &&
2639 net_ratelimit())
2640 PRINT_WARN("Switch to alloc skb\n");
2641 atomic_set(&card->force_alloc_skb, 3);
2642 count = newcount;
2643 } else {
2644 if ((atomic_read(&card->force_alloc_skb) == 1) &&
2645 net_ratelimit())
2646 PRINT_WARN("Switch to sg\n");
2647 atomic_add_unless(&card->force_alloc_skb, -1, 0);
2648 }
2649
2650 /*
2651 * according to old code it should be avoided to requeue all
2652 * 128 buffers in order to benefit from PCI avoidance.
2653 * this function keeps at least one buffer (the buffer at
2654 * 'index') un-requeued -> this buffer is the first buffer that
2655 * will be requeued the next time
2656 */
2657 if (card->options.performance_stats) {
2658 card->perf_stats.inbound_do_qdio_cnt++;
2659 card->perf_stats.inbound_do_qdio_start_time =
2660 qeth_get_micros();
2661 }
2662 rc = do_QDIO(CARD_DDEV(card),
2663 QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT,
2664 0, queue->next_buf_to_init, count, NULL);
2665 if (card->options.performance_stats)
2666 card->perf_stats.inbound_do_qdio_time +=
2667 qeth_get_micros() -
2668 card->perf_stats.inbound_do_qdio_start_time;
2669 if (rc) {
2670 PRINT_WARN("qeth_queue_input_buffer's do_QDIO "
2671 "return %i (device %s).\n",
2672 rc, CARD_DDEV_ID(card));
2673 QETH_DBF_TEXT(trace, 2, "qinberr");
2674 QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
2675 }
2676 queue->next_buf_to_init = (queue->next_buf_to_init + count) %
2677 QDIO_MAX_BUFFERS_PER_Q;
2678 }
2679}
2680EXPORT_SYMBOL_GPL(qeth_queue_input_buffer);
2681
2682static int qeth_handle_send_error(struct qeth_card *card,
2683 struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err,
2684 unsigned int siga_err)
2685{
2686 int sbalf15 = buffer->buffer->element[15].flags & 0xff;
2687 int cc = siga_err & 3;
2688
2689 QETH_DBF_TEXT(trace, 6, "hdsnderr");
2690 qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr");
2691 switch (cc) {
2692 case 0:
2693 if (qdio_err) {
2694 QETH_DBF_TEXT(trace, 1, "lnkfail");
2695 QETH_DBF_TEXT_(trace, 1, "%s", CARD_BUS_ID(card));
2696 QETH_DBF_TEXT_(trace, 1, "%04x %02x",
2697 (u16)qdio_err, (u8)sbalf15);
2698 return QETH_SEND_ERROR_LINK_FAILURE;
2699 }
2700 return QETH_SEND_ERROR_NONE;
2701 case 2:
2702 if (siga_err & QDIO_SIGA_ERROR_B_BIT_SET) {
2703 QETH_DBF_TEXT(trace, 1, "SIGAcc2B");
2704 QETH_DBF_TEXT_(trace, 1, "%s", CARD_BUS_ID(card));
2705 return QETH_SEND_ERROR_KICK_IT;
2706 }
2707 if ((sbalf15 >= 15) && (sbalf15 <= 31))
2708 return QETH_SEND_ERROR_RETRY;
2709 return QETH_SEND_ERROR_LINK_FAILURE;
2710 /* look at qdio_error and sbalf 15 */
2711 case 1:
2712 QETH_DBF_TEXT(trace, 1, "SIGAcc1");
2713 QETH_DBF_TEXT_(trace, 1, "%s", CARD_BUS_ID(card));
2714 return QETH_SEND_ERROR_LINK_FAILURE;
2715 case 3:
2716 default:
2717 QETH_DBF_TEXT(trace, 1, "SIGAcc3");
2718 QETH_DBF_TEXT_(trace, 1, "%s", CARD_BUS_ID(card));
2719 return QETH_SEND_ERROR_KICK_IT;
2720 }
2721}
2722
2723/*
2724 * Switched to packing state if the number of used buffers on a queue
2725 * reaches a certain limit.
2726 */
2727static void qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
2728{
2729 if (!queue->do_pack) {
2730 if (atomic_read(&queue->used_buffers)
2731 >= QETH_HIGH_WATERMARK_PACK){
2732 /* switch non-PACKING -> PACKING */
2733 QETH_DBF_TEXT(trace, 6, "np->pack");
2734 if (queue->card->options.performance_stats)
2735 queue->card->perf_stats.sc_dp_p++;
2736 queue->do_pack = 1;
2737 }
2738 }
2739}
2740
2741/*
2742 * Switches from packing to non-packing mode. If there is a packing
2743 * buffer on the queue this buffer will be prepared to be flushed.
2744 * In that case 1 is returned to inform the caller. If no buffer
2745 * has to be flushed, zero is returned.
2746 */
2747static int qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
2748{
2749 struct qeth_qdio_out_buffer *buffer;
2750 int flush_count = 0;
2751
2752 if (queue->do_pack) {
2753 if (atomic_read(&queue->used_buffers)
2754 <= QETH_LOW_WATERMARK_PACK) {
2755 /* switch PACKING -> non-PACKING */
2756 QETH_DBF_TEXT(trace, 6, "pack->np");
2757 if (queue->card->options.performance_stats)
2758 queue->card->perf_stats.sc_p_dp++;
2759 queue->do_pack = 0;
2760 /* flush packing buffers */
2761 buffer = &queue->bufs[queue->next_buf_to_fill];
2762 if ((atomic_read(&buffer->state) ==
2763 QETH_QDIO_BUF_EMPTY) &&
2764 (buffer->next_element_to_fill > 0)) {
2765 atomic_set(&buffer->state,
2766 QETH_QDIO_BUF_PRIMED);
2767 flush_count++;
2768 queue->next_buf_to_fill =
2769 (queue->next_buf_to_fill + 1) %
2770 QDIO_MAX_BUFFERS_PER_Q;
2771 }
2772 }
2773 }
2774 return flush_count;
2775}
2776
2777/*
2778 * Called to flush a packing buffer if no more pci flags are on the queue.
2779 * Checks if there is a packing buffer and prepares it to be flushed.
2780 * In that case returns 1, otherwise zero.
2781 */
2782static int qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
2783{
2784 struct qeth_qdio_out_buffer *buffer;
2785
2786 buffer = &queue->bufs[queue->next_buf_to_fill];
2787 if ((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
2788 (buffer->next_element_to_fill > 0)) {
2789 /* it's a packing buffer */
2790 atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
2791 queue->next_buf_to_fill =
2792 (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q;
2793 return 1;
2794 }
2795 return 0;
2796}
2797
2798static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
2799 int index, int count)
2800{
2801 struct qeth_qdio_out_buffer *buf;
2802 int rc;
2803 int i;
2804 unsigned int qdio_flags;
2805
2806 QETH_DBF_TEXT(trace, 6, "flushbuf");
2807
2808 for (i = index; i < index + count; ++i) {
2809 buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
2810 buf->buffer->element[buf->next_element_to_fill - 1].flags |=
2811 SBAL_FLAGS_LAST_ENTRY;
2812
2813 if (queue->card->info.type == QETH_CARD_TYPE_IQD)
2814 continue;
2815
2816 if (!queue->do_pack) {
2817 if ((atomic_read(&queue->used_buffers) >=
2818 (QETH_HIGH_WATERMARK_PACK -
2819 QETH_WATERMARK_PACK_FUZZ)) &&
2820 !atomic_read(&queue->set_pci_flags_count)) {
2821 /* it's likely that we'll go to packing
2822 * mode soon */
2823 atomic_inc(&queue->set_pci_flags_count);
2824 buf->buffer->element[0].flags |= 0x40;
2825 }
2826 } else {
2827 if (!atomic_read(&queue->set_pci_flags_count)) {
2828 /*
2829 * there's no outstanding PCI any more, so we
2830 * have to request a PCI to be sure the the PCI
2831 * will wake at some time in the future then we
2832 * can flush packed buffers that might still be
2833 * hanging around, which can happen if no
2834 * further send was requested by the stack
2835 */
2836 atomic_inc(&queue->set_pci_flags_count);
2837 buf->buffer->element[0].flags |= 0x40;
2838 }
2839 }
2840 }
2841
2842 queue->card->dev->trans_start = jiffies;
2843 if (queue->card->options.performance_stats) {
2844 queue->card->perf_stats.outbound_do_qdio_cnt++;
2845 queue->card->perf_stats.outbound_do_qdio_start_time =
2846 qeth_get_micros();
2847 }
2848 qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
2849 if (under_int)
2850 qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT;
2851 if (atomic_read(&queue->set_pci_flags_count))
2852 qdio_flags |= QDIO_FLAG_PCI_OUT;
2853 rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
2854 queue->queue_no, index, count, NULL);
2855 if (queue->card->options.performance_stats)
2856 queue->card->perf_stats.outbound_do_qdio_time +=
2857 qeth_get_micros() -
2858 queue->card->perf_stats.outbound_do_qdio_start_time;
2859 if (rc) {
2860 QETH_DBF_TEXT(trace, 2, "flushbuf");
2861 QETH_DBF_TEXT_(trace, 2, " err%d", rc);
2862 QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card));
2863 queue->card->stats.tx_errors += count;
2864 /* this must not happen under normal circumstances. if it
2865 * happens something is really wrong -> recover */
2866 qeth_schedule_recovery(queue->card);
2867 return;
2868 }
2869 atomic_add(count, &queue->used_buffers);
2870 if (queue->card->options.performance_stats)
2871 queue->card->perf_stats.bufs_sent += count;
2872}
2873
2874static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
2875{
2876 int index;
2877 int flush_cnt = 0;
2878 int q_was_packing = 0;
2879
2880 /*
2881 * check if weed have to switch to non-packing mode or if
2882 * we have to get a pci flag out on the queue
2883 */
2884 if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) ||
2885 !atomic_read(&queue->set_pci_flags_count)) {
2886 if (atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) ==
2887 QETH_OUT_Q_UNLOCKED) {
2888 /*
2889 * If we get in here, there was no action in
2890 * do_send_packet. So, we check if there is a
2891 * packing buffer to be flushed here.
2892 */
2893 netif_stop_queue(queue->card->dev);
2894 index = queue->next_buf_to_fill;
2895 q_was_packing = queue->do_pack;
2896 /* queue->do_pack may change */
2897 barrier();
2898 flush_cnt += qeth_switch_to_nonpacking_if_needed(queue);
2899 if (!flush_cnt &&
2900 !atomic_read(&queue->set_pci_flags_count))
2901 flush_cnt +=
2902 qeth_flush_buffers_on_no_pci(queue);
2903 if (queue->card->options.performance_stats &&
2904 q_was_packing)
2905 queue->card->perf_stats.bufs_sent_pack +=
2906 flush_cnt;
2907 if (flush_cnt)
2908 qeth_flush_buffers(queue, 1, index, flush_cnt);
2909 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
2910 }
2911 }
2912}
2913
2914void qeth_qdio_output_handler(struct ccw_device *ccwdev, unsigned int status,
2915 unsigned int qdio_error, unsigned int siga_error,
2916 unsigned int __queue, int first_element, int count,
2917 unsigned long card_ptr)
2918{
2919 struct qeth_card *card = (struct qeth_card *) card_ptr;
2920 struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
2921 struct qeth_qdio_out_buffer *buffer;
2922 int i;
2923
2924 QETH_DBF_TEXT(trace, 6, "qdouhdl");
2925 if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
2926 if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
2927 QETH_DBF_TEXT(trace, 2, "achkcond");
2928 QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
2929 QETH_DBF_TEXT_(trace, 2, "%08x", status);
2930 netif_stop_queue(card->dev);
2931 qeth_schedule_recovery(card);
2932 return;
2933 }
2934 }
2935 if (card->options.performance_stats) {
2936 card->perf_stats.outbound_handler_cnt++;
2937 card->perf_stats.outbound_handler_start_time =
2938 qeth_get_micros();
2939 }
2940 for (i = first_element; i < (first_element + count); ++i) {
2941 buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
2942 /*we only handle the KICK_IT error by doing a recovery */
2943 if (qeth_handle_send_error(card, buffer,
2944 qdio_error, siga_error)
2945 == QETH_SEND_ERROR_KICK_IT){
2946 netif_stop_queue(card->dev);
2947 qeth_schedule_recovery(card);
2948 return;
2949 }
2950 qeth_clear_output_buffer(queue, buffer);
2951 }
2952 atomic_sub(count, &queue->used_buffers);
2953 /* check if we need to do something on this outbound queue */
2954 if (card->info.type != QETH_CARD_TYPE_IQD)
2955 qeth_check_outbound_queue(queue);
2956
2957 netif_wake_queue(queue->card->dev);
2958 if (card->options.performance_stats)
2959 card->perf_stats.outbound_handler_time += qeth_get_micros() -
2960 card->perf_stats.outbound_handler_start_time;
2961}
2962EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);
2963
2964int qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
2965{
2966 int cast_type = RTN_UNSPEC;
2967
2968 if (card->info.type == QETH_CARD_TYPE_OSN)
2969 return cast_type;
2970
2971 if (skb->dst && skb->dst->neighbour) {
2972 cast_type = skb->dst->neighbour->type;
2973 if ((cast_type == RTN_BROADCAST) ||
2974 (cast_type == RTN_MULTICAST) ||
2975 (cast_type == RTN_ANYCAST))
2976 return cast_type;
2977 else
2978 return RTN_UNSPEC;
2979 }
2980 /* try something else */
2981 if (skb->protocol == ETH_P_IPV6)
2982 return (skb_network_header(skb)[24] == 0xff) ?
2983 RTN_MULTICAST : 0;
2984 else if (skb->protocol == ETH_P_IP)
2985 return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ?
2986 RTN_MULTICAST : 0;
2987 /* ... */
2988 if (!memcmp(skb->data, skb->dev->broadcast, 6))
2989 return RTN_BROADCAST;
2990 else {
2991 u16 hdr_mac;
2992
2993 hdr_mac = *((u16 *)skb->data);
2994 /* tr multicast? */
2995 switch (card->info.link_type) {
2996 case QETH_LINK_TYPE_HSTR:
2997 case QETH_LINK_TYPE_LANE_TR:
2998 if ((hdr_mac == QETH_TR_MAC_NC) ||
2999 (hdr_mac == QETH_TR_MAC_C))
3000 return RTN_MULTICAST;
3001 break;
3002 /* eth or so multicast? */
3003 default:
3004 if ((hdr_mac == QETH_ETH_MAC_V4) ||
3005 (hdr_mac == QETH_ETH_MAC_V6))
3006 return RTN_MULTICAST;
3007 }
3008 }
3009 return cast_type;
3010}
3011EXPORT_SYMBOL_GPL(qeth_get_cast_type);
3012
3013int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
3014 int ipv, int cast_type)
3015{
3016 if (!ipv && (card->info.type == QETH_CARD_TYPE_OSAE))
3017 return card->qdio.default_out_queue;
3018 switch (card->qdio.no_out_queues) {
3019 case 4:
3020 if (cast_type && card->info.is_multicast_different)
3021 return card->info.is_multicast_different &
3022 (card->qdio.no_out_queues - 1);
3023 if (card->qdio.do_prio_queueing && (ipv == 4)) {
3024 const u8 tos = ip_hdr(skb)->tos;
3025
3026 if (card->qdio.do_prio_queueing ==
3027 QETH_PRIO_Q_ING_TOS) {
3028 if (tos & IP_TOS_NOTIMPORTANT)
3029 return 3;
3030 if (tos & IP_TOS_HIGHRELIABILITY)
3031 return 2;
3032 if (tos & IP_TOS_HIGHTHROUGHPUT)
3033 return 1;
3034 if (tos & IP_TOS_LOWDELAY)
3035 return 0;
3036 }
3037 if (card->qdio.do_prio_queueing ==
3038 QETH_PRIO_Q_ING_PREC)
3039 return 3 - (tos >> 6);
3040 } else if (card->qdio.do_prio_queueing && (ipv == 6)) {
3041 /* TODO: IPv6!!! */
3042 }
3043 return card->qdio.default_out_queue;
3044 case 1: /* fallthrough for single-out-queue 1920-device */
3045 default:
3046 return card->qdio.default_out_queue;
3047 }
3048}
3049EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
3050
3051static void __qeth_free_new_skb(struct sk_buff *orig_skb,
3052 struct sk_buff *new_skb)
3053{
3054 if (orig_skb != new_skb)
3055 dev_kfree_skb_any(new_skb);
3056}
3057
3058static inline struct sk_buff *qeth_realloc_headroom(struct qeth_card *card,
3059 struct sk_buff *skb, int size)
3060{
3061 struct sk_buff *new_skb = skb;
3062
3063 if (skb_headroom(skb) >= size)
3064 return skb;
3065 new_skb = skb_realloc_headroom(skb, size);
3066 if (!new_skb)
3067 PRINT_ERR("Could not realloc headroom for qeth_hdr "
3068 "on interface %s", QETH_CARD_IFNAME(card));
3069 return new_skb;
3070}
3071
3072struct sk_buff *qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb,
3073 struct qeth_hdr **hdr)
3074{
3075 struct sk_buff *new_skb;
3076
3077 QETH_DBF_TEXT(trace, 6, "prepskb");
3078
3079 new_skb = qeth_realloc_headroom(card, skb,
3080 sizeof(struct qeth_hdr));
3081 if (!new_skb)
3082 return NULL;
3083
3084 *hdr = ((struct qeth_hdr *)qeth_push_skb(card, new_skb,
3085 sizeof(struct qeth_hdr)));
3086 if (*hdr == NULL) {
3087 __qeth_free_new_skb(skb, new_skb);
3088 return NULL;
3089 }
3090 return new_skb;
3091}
3092EXPORT_SYMBOL_GPL(qeth_prepare_skb);
3093
3094int qeth_get_elements_no(struct qeth_card *card, void *hdr,
3095 struct sk_buff *skb, int elems)
3096{
3097 int elements_needed = 0;
3098
3099 if (skb_shinfo(skb)->nr_frags > 0)
3100 elements_needed = (skb_shinfo(skb)->nr_frags + 1);
3101 if (elements_needed == 0)
3102 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
3103 + skb->len) >> PAGE_SHIFT);
3104 if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
3105 PRINT_ERR("Invalid size of IP packet "
3106 "(Number=%d / Length=%d). Discarded.\n",
3107 (elements_needed+elems), skb->len);
3108 return 0;
3109 }
3110 return elements_needed;
3111}
3112EXPORT_SYMBOL_GPL(qeth_get_elements_no);
3113
3114static void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
3115 int is_tso, int *next_element_to_fill)
3116{
3117 int length = skb->len;
3118 int length_here;
3119 int element;
3120 char *data;
3121 int first_lap ;
3122
3123 element = *next_element_to_fill;
3124 data = skb->data;
3125 first_lap = (is_tso == 0 ? 1 : 0);
3126
3127 while (length > 0) {
3128 /* length_here is the remaining amount of data in this page */
3129 length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE);
3130 if (length < length_here)
3131 length_here = length;
3132
3133 buffer->element[element].addr = data;
3134 buffer->element[element].length = length_here;
3135 length -= length_here;
3136 if (!length) {
3137 if (first_lap)
3138 buffer->element[element].flags = 0;
3139 else
3140 buffer->element[element].flags =
3141 SBAL_FLAGS_LAST_FRAG;
3142 } else {
3143 if (first_lap)
3144 buffer->element[element].flags =
3145 SBAL_FLAGS_FIRST_FRAG;
3146 else
3147 buffer->element[element].flags =
3148 SBAL_FLAGS_MIDDLE_FRAG;
3149 }
3150 data += length_here;
3151 element++;
3152 first_lap = 0;
3153 }
3154 *next_element_to_fill = element;
3155}
3156
3157static int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
3158 struct qeth_qdio_out_buffer *buf, struct sk_buff *skb)
3159{
3160 struct qdio_buffer *buffer;
3161 struct qeth_hdr_tso *hdr;
3162 int flush_cnt = 0, hdr_len, large_send = 0;
3163
3164 QETH_DBF_TEXT(trace, 6, "qdfillbf");
3165
3166 buffer = buf->buffer;
3167 atomic_inc(&skb->users);
3168 skb_queue_tail(&buf->skb_list, skb);
3169
3170 hdr = (struct qeth_hdr_tso *) skb->data;
3171 /*check first on TSO ....*/
3172 if (hdr->hdr.hdr.l3.id == QETH_HEADER_TYPE_TSO) {
3173 int element = buf->next_element_to_fill;
3174
3175 hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len;
3176 /*fill first buffer entry only with header information */
3177 buffer->element[element].addr = skb->data;
3178 buffer->element[element].length = hdr_len;
3179 buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
3180 buf->next_element_to_fill++;
3181 skb->data += hdr_len;
3182 skb->len -= hdr_len;
3183 large_send = 1;
3184 }
3185 if (skb_shinfo(skb)->nr_frags == 0)
3186 __qeth_fill_buffer(skb, buffer, large_send,
3187 (int *)&buf->next_element_to_fill);
3188 else
3189 __qeth_fill_buffer_frag(skb, buffer, large_send,
3190 (int *)&buf->next_element_to_fill);
3191
3192 if (!queue->do_pack) {
3193 QETH_DBF_TEXT(trace, 6, "fillbfnp");
3194 /* set state to PRIMED -> will be flushed */
3195 atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
3196 flush_cnt = 1;
3197 } else {
3198 QETH_DBF_TEXT(trace, 6, "fillbfpa");
3199 if (queue->card->options.performance_stats)
3200 queue->card->perf_stats.skbs_sent_pack++;
3201 if (buf->next_element_to_fill >=
3202 QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
3203 /*
3204 * packed buffer if full -> set state PRIMED
3205 * -> will be flushed
3206 */
3207 atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
3208 flush_cnt = 1;
3209 }
3210 }
3211 return flush_cnt;
3212}
3213
3214int qeth_do_send_packet_fast(struct qeth_card *card,
3215 struct qeth_qdio_out_q *queue, struct sk_buff *skb,
3216 struct qeth_hdr *hdr, int elements_needed,
3217 struct qeth_eddp_context *ctx)
3218{
3219 struct qeth_qdio_out_buffer *buffer;
3220 int buffers_needed = 0;
3221 int flush_cnt = 0;
3222 int index;
3223
3224 QETH_DBF_TEXT(trace, 6, "dosndpfa");
3225
3226 /* spin until we get the queue ... */
3227 while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
3228 QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
3229 /* ... now we've got the queue */
3230 index = queue->next_buf_to_fill;
3231 buffer = &queue->bufs[queue->next_buf_to_fill];
3232 /*
3233 * check if buffer is empty to make sure that we do not 'overtake'
3234 * ourselves and try to fill a buffer that is already primed
3235 */
3236 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
3237 goto out;
3238 if (ctx == NULL)
3239 queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
3240 QDIO_MAX_BUFFERS_PER_Q;
3241 else {
3242 buffers_needed = qeth_eddp_check_buffers_for_context(queue,
3243 ctx);
3244 if (buffers_needed < 0)
3245 goto out;
3246 queue->next_buf_to_fill =
3247 (queue->next_buf_to_fill + buffers_needed) %
3248 QDIO_MAX_BUFFERS_PER_Q;
3249 }
3250 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
3251 if (ctx == NULL) {
3252 qeth_fill_buffer(queue, buffer, skb);
3253 qeth_flush_buffers(queue, 0, index, 1);
3254 } else {
3255 flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
3256 WARN_ON(buffers_needed != flush_cnt);
3257 qeth_flush_buffers(queue, 0, index, flush_cnt);
3258 }
3259 return 0;
3260out:
3261 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
3262 return -EBUSY;
3263}
3264EXPORT_SYMBOL_GPL(qeth_do_send_packet_fast);
3265
3266int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
3267 struct sk_buff *skb, struct qeth_hdr *hdr,
3268 int elements_needed, struct qeth_eddp_context *ctx)
3269{
3270 struct qeth_qdio_out_buffer *buffer;
3271 int start_index;
3272 int flush_count = 0;
3273 int do_pack = 0;
3274 int tmp;
3275 int rc = 0;
3276
3277 QETH_DBF_TEXT(trace, 6, "dosndpkt");
3278
3279 /* spin until we get the queue ... */
3280 while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
3281 QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
3282 start_index = queue->next_buf_to_fill;
3283 buffer = &queue->bufs[queue->next_buf_to_fill];
3284 /*
3285 * check if buffer is empty to make sure that we do not 'overtake'
3286 * ourselves and try to fill a buffer that is already primed
3287 */
3288 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
3289 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
3290 return -EBUSY;
3291 }
3292 /* check if we need to switch packing state of this queue */
3293 qeth_switch_to_packing_if_needed(queue);
3294 if (queue->do_pack) {
3295 do_pack = 1;
3296 if (ctx == NULL) {
3297 /* does packet fit in current buffer? */
3298 if ((QETH_MAX_BUFFER_ELEMENTS(card) -
3299 buffer->next_element_to_fill) < elements_needed) {
3300 /* ... no -> set state PRIMED */
3301 atomic_set(&buffer->state,
3302 QETH_QDIO_BUF_PRIMED);
3303 flush_count++;
3304 queue->next_buf_to_fill =
3305 (queue->next_buf_to_fill + 1) %
3306 QDIO_MAX_BUFFERS_PER_Q;
3307 buffer = &queue->bufs[queue->next_buf_to_fill];
3308 /* we did a step forward, so check buffer state
3309 * again */
3310 if (atomic_read(&buffer->state) !=
3311 QETH_QDIO_BUF_EMPTY){
3312 qeth_flush_buffers(queue, 0,
3313 start_index, flush_count);
3314 atomic_set(&queue->state,
3315 QETH_OUT_Q_UNLOCKED);
3316 return -EBUSY;
3317 }
3318 }
3319 } else {
3320 /* check if we have enough elements (including following
3321 * free buffers) to handle eddp context */
3322 if (qeth_eddp_check_buffers_for_context(queue, ctx)
3323 < 0) {
3324 if (net_ratelimit())
3325 PRINT_WARN("eddp tx_dropped 1\n");
3326 rc = -EBUSY;
3327 goto out;
3328 }
3329 }
3330 }
3331 if (ctx == NULL)
3332 tmp = qeth_fill_buffer(queue, buffer, skb);
3333 else {
3334 tmp = qeth_eddp_fill_buffer(queue, ctx,
3335 queue->next_buf_to_fill);
3336 if (tmp < 0) {
3337 PRINT_ERR("eddp tx_dropped 2\n");
3338 rc = -EBUSY;
3339 goto out;
3340 }
3341 }
3342 queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
3343 QDIO_MAX_BUFFERS_PER_Q;
3344 flush_count += tmp;
3345out:
3346 if (flush_count)
3347 qeth_flush_buffers(queue, 0, start_index, flush_count);
3348 else if (!atomic_read(&queue->set_pci_flags_count))
3349 atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
3350 /*
3351 * queue->state will go from LOCKED -> UNLOCKED or from
3352 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
3353 * (switch packing state or flush buffer to get another pci flag out).
3354 * In that case we will enter this loop
3355 */
3356 while (atomic_dec_return(&queue->state)) {
3357 flush_count = 0;
3358 start_index = queue->next_buf_to_fill;
3359 /* check if we can go back to non-packing state */
3360 flush_count += qeth_switch_to_nonpacking_if_needed(queue);
3361 /*
3362 * check if we need to flush a packing buffer to get a pci
3363 * flag out on the queue
3364 */
3365 if (!flush_count && !atomic_read(&queue->set_pci_flags_count))
3366 flush_count += qeth_flush_buffers_on_no_pci(queue);
3367 if (flush_count)
3368 qeth_flush_buffers(queue, 0, start_index, flush_count);
3369 }
3370 /* at this point the queue is UNLOCKED again */
3371 if (queue->card->options.performance_stats && do_pack)
3372 queue->card->perf_stats.bufs_sent_pack += flush_count;
3373
3374 return rc;
3375}
3376EXPORT_SYMBOL_GPL(qeth_do_send_packet);
3377
3378static int qeth_setadp_promisc_mode_cb(struct qeth_card *card,
3379 struct qeth_reply *reply, unsigned long data)
3380{
3381 struct qeth_ipa_cmd *cmd;
3382 struct qeth_ipacmd_setadpparms *setparms;
3383
3384 QETH_DBF_TEXT(trace, 4, "prmadpcb");
3385
3386 cmd = (struct qeth_ipa_cmd *) data;
3387 setparms = &(cmd->data.setadapterparms);
3388
3389 qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
3390 if (cmd->hdr.return_code) {
3391 QETH_DBF_TEXT_(trace, 4, "prmrc%2.2x", cmd->hdr.return_code);
3392 setparms->data.mode = SET_PROMISC_MODE_OFF;
3393 }
3394 card->info.promisc_mode = setparms->data.mode;
3395 return 0;
3396}
3397
3398void qeth_setadp_promisc_mode(struct qeth_card *card)
3399{
3400 enum qeth_ipa_promisc_modes mode;
3401 struct net_device *dev = card->dev;
3402 struct qeth_cmd_buffer *iob;
3403 struct qeth_ipa_cmd *cmd;
3404
3405 QETH_DBF_TEXT(trace, 4, "setprom");
3406
3407 if (((dev->flags & IFF_PROMISC) &&
3408 (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
3409 (!(dev->flags & IFF_PROMISC) &&
3410 (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
3411 return;
3412 mode = SET_PROMISC_MODE_OFF;
3413 if (dev->flags & IFF_PROMISC)
3414 mode = SET_PROMISC_MODE_ON;
3415 QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);
3416
3417 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
3418 sizeof(struct qeth_ipacmd_setadpparms));
3419 cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
3420 cmd->data.setadapterparms.data.mode = mode;
3421 qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
3422}
3423EXPORT_SYMBOL_GPL(qeth_setadp_promisc_mode);
3424
3425int qeth_change_mtu(struct net_device *dev, int new_mtu)
3426{
3427 struct qeth_card *card;
3428 char dbf_text[15];
3429
3430 card = netdev_priv(dev);
3431
3432 QETH_DBF_TEXT(trace, 4, "chgmtu");
3433 sprintf(dbf_text, "%8x", new_mtu);
3434 QETH_DBF_TEXT(trace, 4, dbf_text);
3435
3436 if (new_mtu < 64)
3437 return -EINVAL;
3438 if (new_mtu > 65535)
3439 return -EINVAL;
3440 if ((!qeth_is_supported(card, IPA_IP_FRAGMENTATION)) &&
3441 (!qeth_mtu_is_valid(card, new_mtu)))
3442 return -EINVAL;
3443 dev->mtu = new_mtu;
3444 return 0;
3445}
3446EXPORT_SYMBOL_GPL(qeth_change_mtu);
3447
3448struct net_device_stats *qeth_get_stats(struct net_device *dev)
3449{
3450 struct qeth_card *card;
3451
3452 card = netdev_priv(dev);
3453
3454 QETH_DBF_TEXT(trace, 5, "getstat");
3455
3456 return &card->stats;
3457}
3458EXPORT_SYMBOL_GPL(qeth_get_stats);
3459
3460static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
3461 struct qeth_reply *reply, unsigned long data)
3462{
3463 struct qeth_ipa_cmd *cmd;
3464
3465 QETH_DBF_TEXT(trace, 4, "chgmaccb");
3466
3467 cmd = (struct qeth_ipa_cmd *) data;
3468 if (!card->options.layer2 ||
3469 !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
3470 memcpy(card->dev->dev_addr,
3471 &cmd->data.setadapterparms.data.change_addr.addr,
3472 OSA_ADDR_LEN);
3473 card->info.mac_bits |= QETH_LAYER2_MAC_READ;
3474 }
3475 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
3476 return 0;
3477}
3478
3479int qeth_setadpparms_change_macaddr(struct qeth_card *card)
3480{
3481 int rc;
3482 struct qeth_cmd_buffer *iob;
3483 struct qeth_ipa_cmd *cmd;
3484
3485 QETH_DBF_TEXT(trace, 4, "chgmac");
3486
3487 iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS,
3488 sizeof(struct qeth_ipacmd_setadpparms));
3489 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
3490 cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
3491 cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN;
3492 memcpy(&cmd->data.setadapterparms.data.change_addr.addr,
3493 card->dev->dev_addr, OSA_ADDR_LEN);
3494 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_change_macaddr_cb,
3495 NULL);
3496 return rc;
3497}
3498EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);
3499
3500void qeth_tx_timeout(struct net_device *dev)
3501{
3502 struct qeth_card *card;
3503
3504 card = netdev_priv(dev);
3505 card->stats.tx_errors++;
3506 qeth_schedule_recovery(card);
3507}
3508EXPORT_SYMBOL_GPL(qeth_tx_timeout);
3509
3510int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
3511{
3512 struct qeth_card *card = netdev_priv(dev);
3513 int rc = 0;
3514
3515 switch (regnum) {
3516 case MII_BMCR: /* Basic mode control register */
3517 rc = BMCR_FULLDPLX;
3518 if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH) &&
3519 (card->info.link_type != QETH_LINK_TYPE_OSN) &&
3520 (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
3521 rc |= BMCR_SPEED100;
3522 break;
3523 case MII_BMSR: /* Basic mode status register */
3524 rc = BMSR_ERCAP | BMSR_ANEGCOMPLETE | BMSR_LSTATUS |
3525 BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | BMSR_100FULL |
3526 BMSR_100BASE4;
3527 break;
3528 case MII_PHYSID1: /* PHYS ID 1 */
3529 rc = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 8) |
3530 dev->dev_addr[2];
3531 rc = (rc >> 5) & 0xFFFF;
3532 break;
3533 case MII_PHYSID2: /* PHYS ID 2 */
3534 rc = (dev->dev_addr[2] << 10) & 0xFFFF;
3535 break;
3536 case MII_ADVERTISE: /* Advertisement control reg */
3537 rc = ADVERTISE_ALL;
3538 break;
3539 case MII_LPA: /* Link partner ability reg */
3540 rc = LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL |
3541 LPA_100BASE4 | LPA_LPACK;
3542 break;
3543 case MII_EXPANSION: /* Expansion register */
3544 break;
3545 case MII_DCOUNTER: /* disconnect counter */
3546 break;
3547 case MII_FCSCOUNTER: /* false carrier counter */
3548 break;
3549 case MII_NWAYTEST: /* N-way auto-neg test register */
3550 break;
3551 case MII_RERRCOUNTER: /* rx error counter */
3552 rc = card->stats.rx_errors;
3553 break;
3554 case MII_SREVISION: /* silicon revision */
3555 break;
3556 case MII_RESV1: /* reserved 1 */
3557 break;
3558 case MII_LBRERROR: /* loopback, rx, bypass error */
3559 break;
3560 case MII_PHYADDR: /* physical address */
3561 break;
3562 case MII_RESV2: /* reserved 2 */
3563 break;
3564 case MII_TPISTATUS: /* TPI status for 10mbps */
3565 break;
3566 case MII_NCONFIG: /* network interface config */
3567 break;
3568 default:
3569 break;
3570 }
3571 return rc;
3572}
3573EXPORT_SYMBOL_GPL(qeth_mdio_read);
3574
3575static int qeth_send_ipa_snmp_cmd(struct qeth_card *card,
3576 struct qeth_cmd_buffer *iob, int len,
3577 int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
3578 unsigned long),
3579 void *reply_param)
3580{
3581 u16 s1, s2;
3582
3583 QETH_DBF_TEXT(trace, 4, "sendsnmp");
3584
3585 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
3586 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
3587 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
3588 /* adjust PDU length fields in IPA_PDU_HEADER */
3589 s1 = (u32) IPA_PDU_HEADER_SIZE + len;
3590 s2 = (u32) len;
3591 memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
3592 memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
3593 memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
3594 memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
3595 return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
3596 reply_cb, reply_param);
3597}
3598
3599static int qeth_snmp_command_cb(struct qeth_card *card,
3600 struct qeth_reply *reply, unsigned long sdata)
3601{
3602 struct qeth_ipa_cmd *cmd;
3603 struct qeth_arp_query_info *qinfo;
3604 struct qeth_snmp_cmd *snmp;
3605 unsigned char *data;
3606 __u16 data_len;
3607
3608 QETH_DBF_TEXT(trace, 3, "snpcmdcb");
3609
3610 cmd = (struct qeth_ipa_cmd *) sdata;
3611 data = (unsigned char *)((char *)cmd - reply->offset);
3612 qinfo = (struct qeth_arp_query_info *) reply->param;
3613 snmp = &cmd->data.setadapterparms.data.snmp;
3614
3615 if (cmd->hdr.return_code) {
3616 QETH_DBF_TEXT_(trace, 4, "scer1%i", cmd->hdr.return_code);
3617 return 0;
3618 }
3619 if (cmd->data.setadapterparms.hdr.return_code) {
3620 cmd->hdr.return_code =
3621 cmd->data.setadapterparms.hdr.return_code;
3622 QETH_DBF_TEXT_(trace, 4, "scer2%i", cmd->hdr.return_code);
3623 return 0;
3624 }
3625 data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data));
3626 if (cmd->data.setadapterparms.hdr.seq_no == 1)
3627 data_len -= (__u16)((char *)&snmp->data - (char *)cmd);
3628 else
3629 data_len -= (__u16)((char *)&snmp->request - (char *)cmd);
3630
3631 /* check if there is enough room in userspace */
3632 if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
3633 QETH_DBF_TEXT_(trace, 4, "scer3%i", -ENOMEM);
3634 cmd->hdr.return_code = -ENOMEM;
3635 return 0;
3636 }
3637 QETH_DBF_TEXT_(trace, 4, "snore%i",
3638 cmd->data.setadapterparms.hdr.used_total);
3639 QETH_DBF_TEXT_(trace, 4, "sseqn%i",
3640 cmd->data.setadapterparms.hdr.seq_no);
3641 /*copy entries to user buffer*/
3642 if (cmd->data.setadapterparms.hdr.seq_no == 1) {
3643 memcpy(qinfo->udata + qinfo->udata_offset,
3644 (char *)snmp,
3645 data_len + offsetof(struct qeth_snmp_cmd, data));
3646 qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data);
3647 } else {
3648 memcpy(qinfo->udata + qinfo->udata_offset,
3649 (char *)&snmp->request, data_len);
3650 }
3651 qinfo->udata_offset += data_len;
3652 /* check if all replies received ... */
3653 QETH_DBF_TEXT_(trace, 4, "srtot%i",
3654 cmd->data.setadapterparms.hdr.used_total);
3655 QETH_DBF_TEXT_(trace, 4, "srseq%i",
3656 cmd->data.setadapterparms.hdr.seq_no);
3657 if (cmd->data.setadapterparms.hdr.seq_no <
3658 cmd->data.setadapterparms.hdr.used_total)
3659 return 1;
3660 return 0;
3661}
3662
3663int qeth_snmp_command(struct qeth_card *card, char __user *udata)
3664{
3665 struct qeth_cmd_buffer *iob;
3666 struct qeth_ipa_cmd *cmd;
3667 struct qeth_snmp_ureq *ureq;
3668 int req_len;
3669 struct qeth_arp_query_info qinfo = {0, };
3670 int rc = 0;
3671
3672 QETH_DBF_TEXT(trace, 3, "snmpcmd");
3673
3674 if (card->info.guestlan)
3675 return -EOPNOTSUPP;
3676
3677 if ((!qeth_adp_supported(card, IPA_SETADP_SET_SNMP_CONTROL)) &&
3678 (!card->options.layer2)) {
3679 PRINT_WARN("SNMP Query MIBS not supported "
3680 "on %s!\n", QETH_CARD_IFNAME(card));
3681 return -EOPNOTSUPP;
3682 }
3683 /* skip 4 bytes (data_len struct member) to get req_len */
3684 if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
3685 return -EFAULT;
3686 ureq = kmalloc(req_len+sizeof(struct qeth_snmp_ureq_hdr), GFP_KERNEL);
3687 if (!ureq) {
3688 QETH_DBF_TEXT(trace, 2, "snmpnome");
3689 return -ENOMEM;
3690 }
3691 if (copy_from_user(ureq, udata,
3692 req_len + sizeof(struct qeth_snmp_ureq_hdr))) {
3693 kfree(ureq);
3694 return -EFAULT;
3695 }
3696 qinfo.udata_len = ureq->hdr.data_len;
3697 qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL);
3698 if (!qinfo.udata) {
3699 kfree(ureq);
3700 return -ENOMEM;
3701 }
3702 qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr);
3703
3704 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL,
3705 QETH_SNMP_SETADP_CMDLENGTH + req_len);
3706 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
3707 memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
3708 rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
3709 qeth_snmp_command_cb, (void *)&qinfo);
3710 if (rc)
3711 PRINT_WARN("SNMP command failed on %s: (0x%x)\n",
3712 QETH_CARD_IFNAME(card), rc);
3713 else {
3714 if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
3715 rc = -EFAULT;
3716 }
3717
3718 kfree(ureq);
3719 kfree(qinfo.udata);
3720 return rc;
3721}
3722EXPORT_SYMBOL_GPL(qeth_snmp_command);
3723
3724static inline int qeth_get_qdio_q_format(struct qeth_card *card)
3725{
3726 switch (card->info.type) {
3727 case QETH_CARD_TYPE_IQD:
3728 return 2;
3729 default:
3730 return 0;
3731 }
3732}
3733
3734static int qeth_qdio_establish(struct qeth_card *card)
3735{
3736 struct qdio_initialize init_data;
3737 char *qib_param_field;
3738 struct qdio_buffer **in_sbal_ptrs;
3739 struct qdio_buffer **out_sbal_ptrs;
3740 int i, j, k;
3741 int rc = 0;
3742
3743 QETH_DBF_TEXT(setup, 2, "qdioest");
3744
3745 qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char),
3746 GFP_KERNEL);
3747 if (!qib_param_field)
3748 return -ENOMEM;
3749
3750 qeth_create_qib_param_field(card, qib_param_field);
3751 qeth_create_qib_param_field_blkt(card, qib_param_field);
3752
3753 in_sbal_ptrs = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(void *),
3754 GFP_KERNEL);
3755 if (!in_sbal_ptrs) {
3756 kfree(qib_param_field);
3757 return -ENOMEM;
3758 }
3759 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
3760 in_sbal_ptrs[i] = (struct qdio_buffer *)
3761 virt_to_phys(card->qdio.in_q->bufs[i].buffer);
3762
3763 out_sbal_ptrs =
3764 kmalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q *
3765 sizeof(void *), GFP_KERNEL);
3766 if (!out_sbal_ptrs) {
3767 kfree(in_sbal_ptrs);
3768 kfree(qib_param_field);
3769 return -ENOMEM;
3770 }
3771 for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i)
3772 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k) {
3773 out_sbal_ptrs[k] = (struct qdio_buffer *)virt_to_phys(
3774 card->qdio.out_qs[i]->bufs[j].buffer);
3775 }
3776
3777 memset(&init_data, 0, sizeof(struct qdio_initialize));
3778 init_data.cdev = CARD_DDEV(card);
3779 init_data.q_format = qeth_get_qdio_q_format(card);
3780 init_data.qib_param_field_format = 0;
3781 init_data.qib_param_field = qib_param_field;
3782 init_data.min_input_threshold = QETH_MIN_INPUT_THRESHOLD;
3783 init_data.max_input_threshold = QETH_MAX_INPUT_THRESHOLD;
3784 init_data.min_output_threshold = QETH_MIN_OUTPUT_THRESHOLD;
3785 init_data.max_output_threshold = QETH_MAX_OUTPUT_THRESHOLD;
3786 init_data.no_input_qs = 1;
3787 init_data.no_output_qs = card->qdio.no_out_queues;
3788 init_data.input_handler = card->discipline.input_handler;
3789 init_data.output_handler = card->discipline.output_handler;
3790 init_data.int_parm = (unsigned long) card;
3791 init_data.flags = QDIO_INBOUND_0COPY_SBALS |
3792 QDIO_OUTBOUND_0COPY_SBALS |
3793 QDIO_USE_OUTBOUND_PCIS;
3794 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3795 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
3796
3797 if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
3798 QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
3799 rc = qdio_initialize(&init_data);
3800 if (rc)
3801 atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
3802 }
3803 kfree(out_sbal_ptrs);
3804 kfree(in_sbal_ptrs);
3805 kfree(qib_param_field);
3806 return rc;
3807}
3808
3809static void qeth_core_free_card(struct qeth_card *card)
3810{
3811
3812 QETH_DBF_TEXT(setup, 2, "freecrd");
3813 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
3814 qeth_clean_channel(&card->read);
3815 qeth_clean_channel(&card->write);
3816 if (card->dev)
3817 free_netdev(card->dev);
3818 kfree(card->ip_tbd_list);
3819 qeth_free_qdio_buffers(card);
3820 kfree(card);
3821}
3822
3823static struct ccw_device_id qeth_ids[] = {
3824 {CCW_DEVICE(0x1731, 0x01), .driver_info = QETH_CARD_TYPE_OSAE},
3825 {CCW_DEVICE(0x1731, 0x05), .driver_info = QETH_CARD_TYPE_IQD},
3826 {CCW_DEVICE(0x1731, 0x06), .driver_info = QETH_CARD_TYPE_OSN},
3827 {},
3828};
3829MODULE_DEVICE_TABLE(ccw, qeth_ids);
3830
3831static struct ccw_driver qeth_ccw_driver = {
3832 .name = "qeth",
3833 .ids = qeth_ids,
3834 .probe = ccwgroup_probe_ccwdev,
3835 .remove = ccwgroup_remove_ccwdev,
3836};
3837
3838static int qeth_core_driver_group(const char *buf, struct device *root_dev,
3839 unsigned long driver_id)
3840{
3841 const char *start, *end;
3842 char bus_ids[3][BUS_ID_SIZE], *argv[3];
3843 int i;
3844
3845 start = buf;
3846 for (i = 0; i < 3; i++) {
3847 static const char delim[] = { ',', ',', '\n' };
3848 int len;
3849
3850 end = strchr(start, delim[i]);
3851 if (!end)
3852 return -EINVAL;
3853 len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start);
3854 strncpy(bus_ids[i], start, len);
3855 bus_ids[i][len] = '\0';
3856 start = end + 1;
3857 argv[i] = bus_ids[i];
3858 }
3859
3860 return (ccwgroup_create(root_dev, driver_id,
3861 &qeth_ccw_driver, 3, argv));
3862}
3863
3864int qeth_core_hardsetup_card(struct qeth_card *card)
3865{
3866 int retries = 3;
3867 int mpno;
3868 int rc;
3869
3870 QETH_DBF_TEXT(setup, 2, "hrdsetup");
3871 atomic_set(&card->force_alloc_skb, 0);
3872retry:
3873 if (retries < 3) {
3874 PRINT_WARN("Retrying to do IDX activates.\n");
3875 ccw_device_set_offline(CARD_DDEV(card));
3876 ccw_device_set_offline(CARD_WDEV(card));
3877 ccw_device_set_offline(CARD_RDEV(card));
3878 ccw_device_set_online(CARD_RDEV(card));
3879 ccw_device_set_online(CARD_WDEV(card));
3880 ccw_device_set_online(CARD_DDEV(card));
3881 }
3882 rc = qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD);
3883 if (rc == -ERESTARTSYS) {
3884 QETH_DBF_TEXT(setup, 2, "break1");
3885 return rc;
3886 } else if (rc) {
3887 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3888 if (--retries < 0)
3889 goto out;
3890 else
3891 goto retry;
3892 }
3893
3894 rc = qeth_get_unitaddr(card);
3895 if (rc) {
3896 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
3897 return rc;
3898 }
3899
3900 mpno = QETH_MAX_PORTNO;
3901 if (card->info.portno > mpno) {
3902 PRINT_ERR("Device %s does not offer port number %d \n.",
3903 CARD_BUS_ID(card), card->info.portno);
3904 rc = -ENODEV;
3905 goto out;
3906 }
3907 qeth_init_tokens(card);
3908 qeth_init_func_level(card);
3909 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
3910 if (rc == -ERESTARTSYS) {
3911 QETH_DBF_TEXT(setup, 2, "break2");
3912 return rc;
3913 } else if (rc) {
3914 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
3915 if (--retries < 0)
3916 goto out;
3917 else
3918 goto retry;
3919 }
3920 rc = qeth_idx_activate_channel(&card->write, qeth_idx_write_cb);
3921 if (rc == -ERESTARTSYS) {
3922 QETH_DBF_TEXT(setup, 2, "break3");
3923 return rc;
3924 } else if (rc) {
3925 QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
3926 if (--retries < 0)
3927 goto out;
3928 else
3929 goto retry;
3930 }
3931 rc = qeth_mpc_initialize(card);
3932 if (rc) {
3933 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
3934 goto out;
3935 }
3936 return 0;
3937out:
3938 PRINT_ERR("Initialization in hardsetup failed! rc=%d\n", rc);
3939 return rc;
3940}
3941EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card);
3942
3943static inline int qeth_create_skb_frag(struct qdio_buffer_element *element,
3944 struct sk_buff **pskb, int offset, int *pfrag, int data_len)
3945{
3946 struct page *page = virt_to_page(element->addr);
3947 if (*pskb == NULL) {
3948 /* the upper protocol layers assume that there is data in the
3949 * skb itself. Copy a small amount (64 bytes) to make them
3950 * happy. */
3951 *pskb = dev_alloc_skb(64 + ETH_HLEN);
3952 if (!(*pskb))
3953 return -ENOMEM;
3954 skb_reserve(*pskb, ETH_HLEN);
3955 if (data_len <= 64) {
3956 memcpy(skb_put(*pskb, data_len), element->addr + offset,
3957 data_len);
3958 } else {
3959 get_page(page);
3960 memcpy(skb_put(*pskb, 64), element->addr + offset, 64);
3961 skb_fill_page_desc(*pskb, *pfrag, page, offset + 64,
3962 data_len - 64);
3963 (*pskb)->data_len += data_len - 64;
3964 (*pskb)->len += data_len - 64;
3965 (*pskb)->truesize += data_len - 64;
3966 (*pfrag)++;
3967 }
3968 } else {
3969 get_page(page);
3970 skb_fill_page_desc(*pskb, *pfrag, page, offset, data_len);
3971 (*pskb)->data_len += data_len;
3972 (*pskb)->len += data_len;
3973 (*pskb)->truesize += data_len;
3974 (*pfrag)++;
3975 }
3976 return 0;
3977}
3978
3979struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
3980 struct qdio_buffer *buffer,
3981 struct qdio_buffer_element **__element, int *__offset,
3982 struct qeth_hdr **hdr)
3983{
3984 struct qdio_buffer_element *element = *__element;
3985 int offset = *__offset;
3986 struct sk_buff *skb = NULL;
3987 int skb_len;
3988 void *data_ptr;
3989 int data_len;
3990 int headroom = 0;
3991 int use_rx_sg = 0;
3992 int frag = 0;
3993
3994 QETH_DBF_TEXT(trace, 6, "nextskb");
3995 /* qeth_hdr must not cross element boundaries */
3996 if (element->length < offset + sizeof(struct qeth_hdr)) {
3997 if (qeth_is_last_sbale(element))
3998 return NULL;
3999 element++;
4000 offset = 0;
4001 if (element->length < sizeof(struct qeth_hdr))
4002 return NULL;
4003 }
4004 *hdr = element->addr + offset;
4005
4006 offset += sizeof(struct qeth_hdr);
4007 if (card->options.layer2) {
4008 if (card->info.type == QETH_CARD_TYPE_OSN) {
4009 skb_len = (*hdr)->hdr.osn.pdu_length;
4010 headroom = sizeof(struct qeth_hdr);
4011 } else {
4012 skb_len = (*hdr)->hdr.l2.pkt_length;
4013 }
4014 } else {
4015 skb_len = (*hdr)->hdr.l3.length;
4016 headroom = max((int)ETH_HLEN, (int)TR_HLEN);
4017 }
4018
4019 if (!skb_len)
4020 return NULL;
4021
4022 if ((skb_len >= card->options.rx_sg_cb) &&
4023 (!(card->info.type == QETH_CARD_TYPE_OSN)) &&
4024 (!atomic_read(&card->force_alloc_skb))) {
4025 use_rx_sg = 1;
4026 } else {
4027 skb = dev_alloc_skb(skb_len + headroom);
4028 if (!skb)
4029 goto no_mem;
4030 if (headroom)
4031 skb_reserve(skb, headroom);
4032 }
4033
4034 data_ptr = element->addr + offset;
4035 while (skb_len) {
4036 data_len = min(skb_len, (int)(element->length - offset));
4037 if (data_len) {
4038 if (use_rx_sg) {
4039 if (qeth_create_skb_frag(element, &skb, offset,
4040 &frag, data_len))
4041 goto no_mem;
4042 } else {
4043 memcpy(skb_put(skb, data_len), data_ptr,
4044 data_len);
4045 }
4046 }
4047 skb_len -= data_len;
4048 if (skb_len) {
4049 if (qeth_is_last_sbale(element)) {
4050 QETH_DBF_TEXT(trace, 4, "unexeob");
4051 QETH_DBF_TEXT_(trace, 4, "%s",
4052 CARD_BUS_ID(card));
4053 QETH_DBF_TEXT(qerr, 2, "unexeob");
4054 QETH_DBF_TEXT_(qerr, 2, "%s",
4055 CARD_BUS_ID(card));
4056 QETH_DBF_HEX(misc, 4, buffer, sizeof(*buffer));
4057 dev_kfree_skb_any(skb);
4058 card->stats.rx_errors++;
4059 return NULL;
4060 }
4061 element++;
4062 offset = 0;
4063 data_ptr = element->addr;
4064 } else {
4065 offset += data_len;
4066 }
4067 }
4068 *__element = element;
4069 *__offset = offset;
4070 if (use_rx_sg && card->options.performance_stats) {
4071 card->perf_stats.sg_skbs_rx++;
4072 card->perf_stats.sg_frags_rx += skb_shinfo(skb)->nr_frags;
4073 }
4074 return skb;
4075no_mem:
4076 if (net_ratelimit()) {
4077 PRINT_WARN("No memory for packet received on %s.\n",
4078 QETH_CARD_IFNAME(card));
4079 QETH_DBF_TEXT(trace, 2, "noskbmem");
4080 QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
4081 }
4082 card->stats.rx_dropped++;
4083 return NULL;
4084}
4085EXPORT_SYMBOL_GPL(qeth_core_get_next_skb);
4086
4087static void qeth_unregister_dbf_views(void)
4088{
4089 if (qeth_dbf_setup)
4090 debug_unregister(qeth_dbf_setup);
4091 if (qeth_dbf_qerr)
4092 debug_unregister(qeth_dbf_qerr);
4093 if (qeth_dbf_sense)
4094 debug_unregister(qeth_dbf_sense);
4095 if (qeth_dbf_misc)
4096 debug_unregister(qeth_dbf_misc);
4097 if (qeth_dbf_data)
4098 debug_unregister(qeth_dbf_data);
4099 if (qeth_dbf_control)
4100 debug_unregister(qeth_dbf_control);
4101 if (qeth_dbf_trace)
4102 debug_unregister(qeth_dbf_trace);
4103}
4104
4105static int qeth_register_dbf_views(void)
4106{
4107 qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME,
4108 QETH_DBF_SETUP_PAGES,
4109 QETH_DBF_SETUP_NR_AREAS,
4110 QETH_DBF_SETUP_LEN);
4111 qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME,
4112 QETH_DBF_MISC_PAGES,
4113 QETH_DBF_MISC_NR_AREAS,
4114 QETH_DBF_MISC_LEN);
4115 qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME,
4116 QETH_DBF_DATA_PAGES,
4117 QETH_DBF_DATA_NR_AREAS,
4118 QETH_DBF_DATA_LEN);
4119 qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME,
4120 QETH_DBF_CONTROL_PAGES,
4121 QETH_DBF_CONTROL_NR_AREAS,
4122 QETH_DBF_CONTROL_LEN);
4123 qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME,
4124 QETH_DBF_SENSE_PAGES,
4125 QETH_DBF_SENSE_NR_AREAS,
4126 QETH_DBF_SENSE_LEN);
4127 qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME,
4128 QETH_DBF_QERR_PAGES,
4129 QETH_DBF_QERR_NR_AREAS,
4130 QETH_DBF_QERR_LEN);
4131 qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME,
4132 QETH_DBF_TRACE_PAGES,
4133 QETH_DBF_TRACE_NR_AREAS,
4134 QETH_DBF_TRACE_LEN);
4135
4136 if ((qeth_dbf_setup == NULL) || (qeth_dbf_misc == NULL) ||
4137 (qeth_dbf_data == NULL) || (qeth_dbf_control == NULL) ||
4138 (qeth_dbf_sense == NULL) || (qeth_dbf_qerr == NULL) ||
4139 (qeth_dbf_trace == NULL)) {
4140 qeth_unregister_dbf_views();
4141 return -ENOMEM;
4142 }
4143 debug_register_view(qeth_dbf_setup, &debug_hex_ascii_view);
4144 debug_set_level(qeth_dbf_setup, QETH_DBF_SETUP_LEVEL);
4145
4146 debug_register_view(qeth_dbf_misc, &debug_hex_ascii_view);
4147 debug_set_level(qeth_dbf_misc, QETH_DBF_MISC_LEVEL);
4148
4149 debug_register_view(qeth_dbf_data, &debug_hex_ascii_view);
4150 debug_set_level(qeth_dbf_data, QETH_DBF_DATA_LEVEL);
4151
4152 debug_register_view(qeth_dbf_control, &debug_hex_ascii_view);
4153 debug_set_level(qeth_dbf_control, QETH_DBF_CONTROL_LEVEL);
4154
4155 debug_register_view(qeth_dbf_sense, &debug_hex_ascii_view);
4156 debug_set_level(qeth_dbf_sense, QETH_DBF_SENSE_LEVEL);
4157
4158 debug_register_view(qeth_dbf_qerr, &debug_hex_ascii_view);
4159 debug_set_level(qeth_dbf_qerr, QETH_DBF_QERR_LEVEL);
4160
4161 debug_register_view(qeth_dbf_trace, &debug_hex_ascii_view);
4162 debug_set_level(qeth_dbf_trace, QETH_DBF_TRACE_LEVEL);
4163
4164 return 0;
4165}
4166
4167int qeth_core_load_discipline(struct qeth_card *card,
4168 enum qeth_discipline_id discipline)
4169{
4170 int rc = 0;
4171 switch (discipline) {
4172 case QETH_DISCIPLINE_LAYER3:
4173 card->discipline.ccwgdriver = try_then_request_module(
4174 symbol_get(qeth_l3_ccwgroup_driver),
4175 "qeth_l3");
4176 break;
4177 case QETH_DISCIPLINE_LAYER2:
4178 card->discipline.ccwgdriver = try_then_request_module(
4179 symbol_get(qeth_l2_ccwgroup_driver),
4180 "qeth_l2");
4181 break;
4182 }
4183 if (!card->discipline.ccwgdriver) {
4184 PRINT_ERR("Support for discipline %d not present\n",
4185 discipline);
4186 rc = -EINVAL;
4187 }
4188 return rc;
4189}
4190
4191void qeth_core_free_discipline(struct qeth_card *card)
4192{
4193 if (card->options.layer2)
4194 symbol_put(qeth_l2_ccwgroup_driver);
4195 else
4196 symbol_put(qeth_l3_ccwgroup_driver);
4197 card->discipline.ccwgdriver = NULL;
4198}
4199
4200static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4201{
4202 struct qeth_card *card;
4203 struct device *dev;
4204 int rc;
4205 unsigned long flags;
4206
4207 QETH_DBF_TEXT(setup, 2, "probedev");
4208
4209 dev = &gdev->dev;
4210 if (!get_device(dev))
4211 return -ENODEV;
4212
4213 QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
4214
4215 card = qeth_alloc_card();
4216 if (!card) {
4217 QETH_DBF_TEXT_(setup, 2, "1err%d", -ENOMEM);
4218 rc = -ENOMEM;
4219 goto err_dev;
4220 }
4221 card->read.ccwdev = gdev->cdev[0];
4222 card->write.ccwdev = gdev->cdev[1];
4223 card->data.ccwdev = gdev->cdev[2];
4224 dev_set_drvdata(&gdev->dev, card);
4225 card->gdev = gdev;
4226 gdev->cdev[0]->handler = qeth_irq;
4227 gdev->cdev[1]->handler = qeth_irq;
4228 gdev->cdev[2]->handler = qeth_irq;
4229
4230 rc = qeth_determine_card_type(card);
4231 if (rc) {
4232 PRINT_WARN("%s: not a valid card type\n", __func__);
4233 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
4234 goto err_card;
4235 }
4236 rc = qeth_setup_card(card);
4237 if (rc) {
4238 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
4239 goto err_card;
4240 }
4241
4242 if (card->info.type == QETH_CARD_TYPE_OSN) {
4243 rc = qeth_core_create_osn_attributes(dev);
4244 if (rc)
4245 goto err_card;
4246 rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
4247 if (rc) {
4248 qeth_core_remove_osn_attributes(dev);
4249 goto err_card;
4250 }
4251 rc = card->discipline.ccwgdriver->probe(card->gdev);
4252 if (rc) {
4253 qeth_core_free_discipline(card);
4254 qeth_core_remove_osn_attributes(dev);
4255 goto err_card;
4256 }
4257 } else {
4258 rc = qeth_core_create_device_attributes(dev);
4259 if (rc)
4260 goto err_card;
4261 }
4262
4263 write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
4264 list_add_tail(&card->list, &qeth_core_card_list.list);
4265 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
4266 return 0;
4267
4268err_card:
4269 qeth_core_free_card(card);
4270err_dev:
4271 put_device(dev);
4272 return rc;
4273}
4274
4275static void qeth_core_remove_device(struct ccwgroup_device *gdev)
4276{
4277 unsigned long flags;
4278 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4279
4280 if (card->discipline.ccwgdriver) {
4281 card->discipline.ccwgdriver->remove(gdev);
4282 qeth_core_free_discipline(card);
4283 }
4284
4285 if (card->info.type == QETH_CARD_TYPE_OSN) {
4286 qeth_core_remove_osn_attributes(&gdev->dev);
4287 } else {
4288 qeth_core_remove_device_attributes(&gdev->dev);
4289 }
4290 write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
4291 list_del(&card->list);
4292 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
4293 qeth_core_free_card(card);
4294 dev_set_drvdata(&gdev->dev, NULL);
4295 put_device(&gdev->dev);
4296 return;
4297}
4298
4299static int qeth_core_set_online(struct ccwgroup_device *gdev)
4300{
4301 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4302 int rc = 0;
4303 int def_discipline;
4304
4305 if (!card->discipline.ccwgdriver) {
4306 if (card->info.type == QETH_CARD_TYPE_IQD)
4307 def_discipline = QETH_DISCIPLINE_LAYER3;
4308 else
4309 def_discipline = QETH_DISCIPLINE_LAYER2;
4310 rc = qeth_core_load_discipline(card, def_discipline);
4311 if (rc)
4312 goto err;
4313 rc = card->discipline.ccwgdriver->probe(card->gdev);
4314 if (rc)
4315 goto err;
4316 }
4317 rc = card->discipline.ccwgdriver->set_online(gdev);
4318err:
4319 return rc;
4320}
4321
4322static int qeth_core_set_offline(struct ccwgroup_device *gdev)
4323{
4324 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4325 return card->discipline.ccwgdriver->set_offline(gdev);
4326}
4327
4328static void qeth_core_shutdown(struct ccwgroup_device *gdev)
4329{
4330 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4331 if (card->discipline.ccwgdriver &&
4332 card->discipline.ccwgdriver->shutdown)
4333 card->discipline.ccwgdriver->shutdown(gdev);
4334}
4335
4336static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
4337 .owner = THIS_MODULE,
4338 .name = "qeth",
4339 .driver_id = 0xD8C5E3C8,
4340 .probe = qeth_core_probe_device,
4341 .remove = qeth_core_remove_device,
4342 .set_online = qeth_core_set_online,
4343 .set_offline = qeth_core_set_offline,
4344 .shutdown = qeth_core_shutdown,
4345};
4346
4347static ssize_t
4348qeth_core_driver_group_store(struct device_driver *ddrv, const char *buf,
4349 size_t count)
4350{
4351 int err;
4352 err = qeth_core_driver_group(buf, qeth_core_root_dev,
4353 qeth_core_ccwgroup_driver.driver_id);
4354 if (err)
4355 return err;
4356 else
4357 return count;
4358}
4359
4360static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store);
4361
4362static struct {
4363 const char str[ETH_GSTRING_LEN];
4364} qeth_ethtool_stats_keys[] = {
4365/* 0 */{"rx skbs"},
4366 {"rx buffers"},
4367 {"tx skbs"},
4368 {"tx buffers"},
4369 {"tx skbs no packing"},
4370 {"tx buffers no packing"},
4371 {"tx skbs packing"},
4372 {"tx buffers packing"},
4373 {"tx sg skbs"},
4374 {"tx sg frags"},
4375/* 10 */{"rx sg skbs"},
4376 {"rx sg frags"},
4377 {"rx sg page allocs"},
4378 {"tx large kbytes"},
4379 {"tx large count"},
4380 {"tx pk state ch n->p"},
4381 {"tx pk state ch p->n"},
4382 {"tx pk watermark low"},
4383 {"tx pk watermark high"},
4384 {"queue 0 buffer usage"},
4385/* 20 */{"queue 1 buffer usage"},
4386 {"queue 2 buffer usage"},
4387 {"queue 3 buffer usage"},
4388 {"rx handler time"},
4389 {"rx handler count"},
4390 {"rx do_QDIO time"},
4391 {"rx do_QDIO count"},
4392 {"tx handler time"},
4393 {"tx handler count"},
4394 {"tx time"},
4395/* 30 */{"tx count"},
4396 {"tx do_QDIO time"},
4397 {"tx do_QDIO count"},
4398};
4399
4400int qeth_core_get_stats_count(struct net_device *dev)
4401{
4402 return (sizeof(qeth_ethtool_stats_keys) / ETH_GSTRING_LEN);
4403}
4404EXPORT_SYMBOL_GPL(qeth_core_get_stats_count);
4405
4406void qeth_core_get_ethtool_stats(struct net_device *dev,
4407 struct ethtool_stats *stats, u64 *data)
4408{
4409 struct qeth_card *card = netdev_priv(dev);
4410 data[0] = card->stats.rx_packets -
4411 card->perf_stats.initial_rx_packets;
4412 data[1] = card->perf_stats.bufs_rec;
4413 data[2] = card->stats.tx_packets -
4414 card->perf_stats.initial_tx_packets;
4415 data[3] = card->perf_stats.bufs_sent;
4416 data[4] = card->stats.tx_packets - card->perf_stats.initial_tx_packets
4417 - card->perf_stats.skbs_sent_pack;
4418 data[5] = card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack;
4419 data[6] = card->perf_stats.skbs_sent_pack;
4420 data[7] = card->perf_stats.bufs_sent_pack;
4421 data[8] = card->perf_stats.sg_skbs_sent;
4422 data[9] = card->perf_stats.sg_frags_sent;
4423 data[10] = card->perf_stats.sg_skbs_rx;
4424 data[11] = card->perf_stats.sg_frags_rx;
4425 data[12] = card->perf_stats.sg_alloc_page_rx;
4426 data[13] = (card->perf_stats.large_send_bytes >> 10);
4427 data[14] = card->perf_stats.large_send_cnt;
4428 data[15] = card->perf_stats.sc_dp_p;
4429 data[16] = card->perf_stats.sc_p_dp;
4430 data[17] = QETH_LOW_WATERMARK_PACK;
4431 data[18] = QETH_HIGH_WATERMARK_PACK;
4432 data[19] = atomic_read(&card->qdio.out_qs[0]->used_buffers);
4433 data[20] = (card->qdio.no_out_queues > 1) ?
4434 atomic_read(&card->qdio.out_qs[1]->used_buffers) : 0;
4435 data[21] = (card->qdio.no_out_queues > 2) ?
4436 atomic_read(&card->qdio.out_qs[2]->used_buffers) : 0;
4437 data[22] = (card->qdio.no_out_queues > 3) ?
4438 atomic_read(&card->qdio.out_qs[3]->used_buffers) : 0;
4439 data[23] = card->perf_stats.inbound_time;
4440 data[24] = card->perf_stats.inbound_cnt;
4441 data[25] = card->perf_stats.inbound_do_qdio_time;
4442 data[26] = card->perf_stats.inbound_do_qdio_cnt;
4443 data[27] = card->perf_stats.outbound_handler_time;
4444 data[28] = card->perf_stats.outbound_handler_cnt;
4445 data[29] = card->perf_stats.outbound_time;
4446 data[30] = card->perf_stats.outbound_cnt;
4447 data[31] = card->perf_stats.outbound_do_qdio_time;
4448 data[32] = card->perf_stats.outbound_do_qdio_cnt;
4449}
4450EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
4451
4452void qeth_core_get_strings(struct net_device *dev, u32 stringset, u8 *data)
4453{
4454 switch (stringset) {
4455 case ETH_SS_STATS:
4456 memcpy(data, &qeth_ethtool_stats_keys,
4457 sizeof(qeth_ethtool_stats_keys));
4458 break;
4459 default:
4460 WARN_ON(1);
4461 break;
4462 }
4463}
4464EXPORT_SYMBOL_GPL(qeth_core_get_strings);
4465
4466void qeth_core_get_drvinfo(struct net_device *dev,
4467 struct ethtool_drvinfo *info)
4468{
4469 struct qeth_card *card = netdev_priv(dev);
4470 if (card->options.layer2)
4471 strcpy(info->driver, "qeth_l2");
4472 else
4473 strcpy(info->driver, "qeth_l3");
4474
4475 strcpy(info->version, "1.0");
4476 strcpy(info->fw_version, card->info.mcl_level);
4477 sprintf(info->bus_info, "%s/%s/%s",
4478 CARD_RDEV_ID(card),
4479 CARD_WDEV_ID(card),
4480 CARD_DDEV_ID(card));
4481}
4482EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo);
4483
4484static int __init qeth_core_init(void)
4485{
4486 int rc;
4487
4488 PRINT_INFO("loading core functions\n");
4489 INIT_LIST_HEAD(&qeth_core_card_list.list);
4490 rwlock_init(&qeth_core_card_list.rwlock);
4491
4492 rc = qeth_register_dbf_views();
4493 if (rc)
4494 goto out_err;
4495 rc = ccw_driver_register(&qeth_ccw_driver);
4496 if (rc)
4497 goto ccw_err;
4498 rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver);
4499 if (rc)
4500 goto ccwgroup_err;
4501 rc = driver_create_file(&qeth_core_ccwgroup_driver.driver,
4502 &driver_attr_group);
4503 if (rc)
4504 goto driver_err;
4505 qeth_core_root_dev = s390_root_dev_register("qeth");
4506 rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0;
4507 if (rc)
4508 goto register_err;
4509 return 0;
4510
4511register_err:
4512 driver_remove_file(&qeth_core_ccwgroup_driver.driver,
4513 &driver_attr_group);
4514driver_err:
4515 ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
4516ccwgroup_err:
4517 ccw_driver_unregister(&qeth_ccw_driver);
4518ccw_err:
4519 qeth_unregister_dbf_views();
4520out_err:
4521 PRINT_ERR("Initialization failed with code %d\n", rc);
4522 return rc;
4523}
4524
4525static void __exit qeth_core_exit(void)
4526{
4527 s390_root_dev_unregister(qeth_core_root_dev);
4528 driver_remove_file(&qeth_core_ccwgroup_driver.driver,
4529 &driver_attr_group);
4530 ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
4531 ccw_driver_unregister(&qeth_ccw_driver);
4532 qeth_unregister_dbf_views();
4533 PRINT_INFO("core functions removed\n");
4534}
4535
4536module_init(qeth_core_init);
4537module_exit(qeth_core_exit);
4538MODULE_AUTHOR("Frank Blaschka <frank.blaschka@de.ibm.com>");
4539MODULE_DESCRIPTION("qeth core functions");
4540MODULE_LICENSE("GPL");
diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c
new file mode 100644
index 000000000000..8653b73e5dcf
--- /dev/null
+++ b/drivers/s390/net/qeth_core_mpc.c
@@ -0,0 +1,266 @@
1/*
2 * drivers/s390/net/qeth_core_mpc.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Frank Pavlic <fpavlic@de.ibm.com>,
6 * Thomas Spatzier <tspat@de.ibm.com>,
7 * Frank Blaschka <frank.blaschka@de.ibm.com>
8 */
9
10#include <linux/module.h>
11#include <asm/cio.h>
12#include "qeth_core_mpc.h"
13
14unsigned char IDX_ACTIVATE_READ[] = {
15 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
16 0x19, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
17 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc1,
18 0xd3, 0xd3, 0xd6, 0xd3, 0xc5, 0x40, 0x00, 0x00,
19 0x00, 0x00
20};
21
22unsigned char IDX_ACTIVATE_WRITE[] = {
23 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x15, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
25 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc1,
26 0xd3, 0xd3, 0xd6, 0xd3, 0xc5, 0x40, 0x00, 0x00,
27 0x00, 0x00
28};
29
30unsigned char CM_ENABLE[] = {
31 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
32 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x63,
33 0x10, 0x00, 0x00, 0x01,
34 0x00, 0x00, 0x00, 0x00,
35 0x81, 0x7e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x23,
37 0x00, 0x00, 0x23, 0x05, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x40,
40 0x00, 0x0c, 0x41, 0x02, 0x00, 0x17, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x0b, 0x04, 0x01,
43 0x7e, 0x04, 0x05, 0x00, 0x01, 0x01, 0x0f,
44 0x00,
45 0x0c, 0x04, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff,
46 0xff, 0xff, 0xff
47};
48
49unsigned char CM_SETUP[] = {
50 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
51 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x64,
52 0x10, 0x00, 0x00, 0x01,
53 0x00, 0x00, 0x00, 0x00,
54 0x81, 0x7e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x24,
56 0x00, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x40,
59 0x00, 0x0c, 0x41, 0x04, 0x00, 0x18, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x09, 0x04, 0x04,
62 0x05, 0x00, 0x01, 0x01, 0x11,
63 0x00, 0x09, 0x04,
64 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x06,
66 0x04, 0x06, 0xc8, 0x00
67};
68
69unsigned char ULP_ENABLE[] = {
70 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
71 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6b,
72 0x10, 0x00, 0x00, 0x01,
73 0x00, 0x00, 0x00, 0x00,
74 0x41, 0x7e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x2b,
76 0x00, 0x00, 0x2b, 0x05, 0x20, 0x01, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x40,
79 0x00, 0x0c, 0x41, 0x02, 0x00, 0x1f, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x0b, 0x04, 0x01,
82 0x03, 0x04, 0x05, 0x00, 0x01, 0x01, 0x12,
83 0x00,
84 0x14, 0x04, 0x0a, 0x00, 0x20, 0x00, 0x00, 0xff,
85 0xff, 0x00, 0x08, 0xc8, 0xe8, 0xc4, 0xf1, 0xc7,
86 0xf1, 0x00, 0x00
87};
88
89unsigned char ULP_SETUP[] = {
90 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
91 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6c,
92 0x10, 0x00, 0x00, 0x01,
93 0x00, 0x00, 0x00, 0x00,
94 0x41, 0x7e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
95 0x00, 0x00, 0x00, 0x01, 0x00, 0x24, 0x00, 0x2c,
96 0x00, 0x00, 0x2c, 0x05, 0x20, 0x01, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x01, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x40,
99 0x00, 0x0c, 0x41, 0x04, 0x00, 0x20, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x09, 0x04, 0x04,
102 0x05, 0x00, 0x01, 0x01, 0x14,
103 0x00, 0x09, 0x04,
104 0x05, 0x05, 0x30, 0x01, 0x00, 0x00,
105 0x00, 0x06,
106 0x04, 0x06, 0x40, 0x00,
107 0x00, 0x08, 0x04, 0x0b,
108 0x00, 0x00, 0x00, 0x00
109};
110
111unsigned char DM_ACT[] = {
112 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
113 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x55,
114 0x10, 0x00, 0x00, 0x01,
115 0x00, 0x00, 0x00, 0x00,
116 0x41, 0x7e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
117 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x15,
118 0x00, 0x00, 0x2c, 0x05, 0x20, 0x01, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x40,
121 0x00, 0x0c, 0x43, 0x60, 0x00, 0x09, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x09, 0x04, 0x04,
124 0x05, 0x40, 0x01, 0x01, 0x00
125};
126
127unsigned char IPA_PDU_HEADER[] = {
128 0x00, 0xe0, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77,
129 0x00, 0x00, 0x00, 0x14, 0x00, 0x00,
130 (IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd)) / 256,
131 (IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd)) % 256,
132 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
133 0xc1, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x24,
135 sizeof(struct qeth_ipa_cmd) / 256,
136 sizeof(struct qeth_ipa_cmd) % 256,
137 0x00,
138 sizeof(struct qeth_ipa_cmd) / 256,
139 sizeof(struct qeth_ipa_cmd) % 256,
140 0x05,
141 0x77, 0x77, 0x77, 0x77,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x01, 0x00,
144 sizeof(struct qeth_ipa_cmd) / 256,
145 sizeof(struct qeth_ipa_cmd) % 256,
146 0x00, 0x00, 0x00, 0x40,
147};
148EXPORT_SYMBOL_GPL(IPA_PDU_HEADER);
149
150unsigned char WRITE_CCW[] = {
151 0x01, CCW_FLAG_SLI, 0, 0,
152 0, 0, 0, 0
153};
154
155unsigned char READ_CCW[] = {
156 0x02, CCW_FLAG_SLI, 0, 0,
157 0, 0, 0, 0
158};
159
160
161struct ipa_rc_msg {
162 enum qeth_ipa_return_codes rc;
163 char *msg;
164};
165
166static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
167 {IPA_RC_SUCCESS, "success"},
168 {IPA_RC_NOTSUPP, "Command not supported"},
169 {IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"},
170 {IPA_RC_UNKNOWN_ERROR, "IPA command failed - reason unknown"},
171 {IPA_RC_UNSUPPORTED_COMMAND, "Command not supported"},
172 {IPA_RC_DUP_IPV6_REMOTE, "ipv6 address already registered remote"},
173 {IPA_RC_DUP_IPV6_HOME, "ipv6 address already registered"},
174 {IPA_RC_UNREGISTERED_ADDR, "Address not registered"},
175 {IPA_RC_NO_ID_AVAILABLE, "No identifiers available"},
176 {IPA_RC_ID_NOT_FOUND, "Identifier not found"},
177 {IPA_RC_INVALID_IP_VERSION, "IP version incorrect"},
178 {IPA_RC_LAN_FRAME_MISMATCH, "LAN and frame mismatch"},
179 {IPA_RC_L2_UNSUPPORTED_CMD, "Unsupported layer 2 command"},
180 {IPA_RC_L2_DUP_MAC, "Duplicate MAC address"},
181 {IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"},
182 {IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"},
183 {IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"},
184 {IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"},
185 {IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"},
186 {IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"},
187 {IPA_RC_L2_VLAN_ID_NOT_FOUND, "L2 vlan id not found"},
188 {IPA_RC_DATA_MISMATCH, "Data field mismatch (v4/v6 mixed)"},
189 {IPA_RC_INVALID_MTU_SIZE, "Invalid MTU size"},
190 {IPA_RC_INVALID_LANTYPE, "Invalid LAN type"},
191 {IPA_RC_INVALID_LANNUM, "Invalid LAN num"},
192 {IPA_RC_DUPLICATE_IP_ADDRESS, "Address already registered"},
193 {IPA_RC_IP_ADDR_TABLE_FULL, "IP address table full"},
194 {IPA_RC_LAN_PORT_STATE_ERROR, "LAN port state error"},
195 {IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"},
196 {IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"},
197 {IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"},
198 {IPA_RC_MULTICAST_FULL, "No task available, multicast full"},
199 {IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"},
200 {IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"},
201 {IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"},
202 {IPA_RC_PRIMARY_ALREADY_DEFINED, "Primary already defined"},
203 {IPA_RC_SECOND_ALREADY_DEFINED, "Secondary already defined"},
204 {IPA_RC_INVALID_SETRTG_INDICATOR, "Invalid SETRTG indicator"},
205 {IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"},
206 {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
207 {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
208 {IPA_RC_FFFF, "Unknown Error"}
209};
210
211
212
213char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
214{
215 int x = 0;
216 qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) /
217 sizeof(struct ipa_rc_msg) - 1].rc = rc;
218 while (qeth_ipa_rc_msg[x].rc != rc)
219 x++;
220 return qeth_ipa_rc_msg[x].msg;
221}
222
223
224struct ipa_cmd_names {
225 enum qeth_ipa_cmds cmd;
226 char *name;
227};
228
229static struct ipa_cmd_names qeth_ipa_cmd_names[] = {
230 {IPA_CMD_STARTLAN, "startlan"},
231 {IPA_CMD_STOPLAN, "stoplan"},
232 {IPA_CMD_SETVMAC, "setvmac"},
233 {IPA_CMD_DELVMAC, "delvmca"},
234 {IPA_CMD_SETGMAC, "setgmac"},
235 {IPA_CMD_DELGMAC, "delgmac"},
236 {IPA_CMD_SETVLAN, "setvlan"},
237 {IPA_CMD_DELVLAN, "delvlan"},
238 {IPA_CMD_SETCCID, "setccid"},
239 {IPA_CMD_DELCCID, "delccid"},
240 {IPA_CMD_MODCCID, "modccid"},
241 {IPA_CMD_SETIP, "setip"},
242 {IPA_CMD_QIPASSIST, "qipassist"},
243 {IPA_CMD_SETASSPARMS, "setassparms"},
244 {IPA_CMD_SETIPM, "setipm"},
245 {IPA_CMD_DELIPM, "delipm"},
246 {IPA_CMD_SETRTG, "setrtg"},
247 {IPA_CMD_DELIP, "delip"},
248 {IPA_CMD_SETADAPTERPARMS, "setadapterparms"},
249 {IPA_CMD_SET_DIAG_ASS, "set_diag_ass"},
250 {IPA_CMD_CREATE_ADDR, "create_addr"},
251 {IPA_CMD_DESTROY_ADDR, "destroy_addr"},
252 {IPA_CMD_REGISTER_LOCAL_ADDR, "register_local_addr"},
253 {IPA_CMD_UNREGISTER_LOCAL_ADDR, "unregister_local_addr"},
254 {IPA_CMD_UNKNOWN, "unknown"},
255};
256
257char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
258{
259 int x = 0;
260 qeth_ipa_cmd_names[
261 sizeof(qeth_ipa_cmd_names) /
262 sizeof(struct ipa_cmd_names)-1].cmd = cmd;
263 while (qeth_ipa_cmd_names[x].cmd != cmd)
264 x++;
265 return qeth_ipa_cmd_names[x].name;
266}
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 6de2da5ed5fd..de221932f30f 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -1,27 +1,25 @@
1/* 1/*
2 * linux/drivers/s390/net/qeth_mpc.h 2 * drivers/s390/net/qeth_core_mpc.h
3 *
4 * Linux on zSeries OSA Express and HiperSockets support
5 *
6 * Copyright 2000,2003 IBM Corporation
7 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
8 * Thomas Spatzier <tspat@de.ibm.com>
9 * Frank Pavlic <fpavlic@de.ibm.com>
10 * 3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Frank Pavlic <fpavlic@de.ibm.com>,
6 * Thomas Spatzier <tspat@de.ibm.com>,
7 * Frank Blaschka <frank.blaschka@de.ibm.com>
11 */ 8 */
12#ifndef __QETH_MPC_H__ 9
13#define __QETH_MPC_H__ 10#ifndef __QETH_CORE_MPC_H__
11#define __QETH_CORE_MPC_H__
14 12
15#include <asm/qeth.h> 13#include <asm/qeth.h>
16 14
17#define IPA_PDU_HEADER_SIZE 0x40 15#define IPA_PDU_HEADER_SIZE 0x40
18#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e) 16#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer + 0x0e)
19#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26) 17#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer + 0x26)
20#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x29) 18#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer + 0x29)
21#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a) 19#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer + 0x3a)
22 20
23extern unsigned char IPA_PDU_HEADER[]; 21extern unsigned char IPA_PDU_HEADER[];
24#define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer+0x2c) 22#define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer + 0x2c)
25 23
26#define IPA_CMD_LENGTH (IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd)) 24#define IPA_CMD_LENGTH (IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd))
27 25
@@ -93,7 +91,8 @@ enum qeth_checksum_types {
93 */ 91 */
94#define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */ 92#define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */
95enum qeth_routing_types { 93enum qeth_routing_types {
96 NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */ 94 /* TODO: set to bit flag used in IPA Command */
95 NO_ROUTER = 0,
97 PRIMARY_ROUTER = 1, 96 PRIMARY_ROUTER = 1,
98 SECONDARY_ROUTER = 2, 97 SECONDARY_ROUTER = 2,
99 MULTICAST_ROUTER = 3, 98 MULTICAST_ROUTER = 3,
@@ -233,14 +232,14 @@ enum qeth_ipa_setdelip_flags {
233 232
234/* SETADAPTER IPA Command: ****************************************************/ 233/* SETADAPTER IPA Command: ****************************************************/
235enum qeth_ipa_setadp_cmd { 234enum qeth_ipa_setadp_cmd {
236 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x01, 235 IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x0001,
237 IPA_SETADP_ALTER_MAC_ADDRESS = 0x02, 236 IPA_SETADP_ALTER_MAC_ADDRESS = 0x0002,
238 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04, 237 IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x0004,
239 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08, 238 IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x0008,
240 IPA_SETADP_SET_ADDRESSING_MODE = 0x10, 239 IPA_SETADP_SET_ADDRESSING_MODE = 0x0010,
241 IPA_SETADP_SET_CONFIG_PARMS = 0x20, 240 IPA_SETADP_SET_CONFIG_PARMS = 0x0020,
242 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40, 241 IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x0040,
243 IPA_SETADP_SET_BROADCAST_MODE = 0x80, 242 IPA_SETADP_SET_BROADCAST_MODE = 0x0080,
244 IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, 243 IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
245 IPA_SETADP_SET_SNMP_CONTROL = 0x0200, 244 IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
246 IPA_SETADP_QUERY_CARD_INFO = 0x0400, 245 IPA_SETADP_QUERY_CARD_INFO = 0x0400,
@@ -397,26 +396,11 @@ struct qeth_ipacmd_setadpparms {
397 } data; 396 } data;
398} __attribute__ ((packed)); 397} __attribute__ ((packed));
399 398
400/* IPFRAME IPA Command: ***************************************************/
401/* TODO: define in analogy to commands define above */
402
403/* ADD_ADDR_ENTRY IPA Command: ********************************************/
404/* TODO: define in analogy to commands define above */
405
406/* DELETE_ADDR_ENTRY IPA Command: *****************************************/
407/* TODO: define in analogy to commands define above */
408
409/* CREATE_ADDR IPA Command: ***********************************************/ 399/* CREATE_ADDR IPA Command: ***********************************************/
410struct qeth_create_destroy_address { 400struct qeth_create_destroy_address {
411 __u8 unique_id[8]; 401 __u8 unique_id[8];
412} __attribute__ ((packed)); 402} __attribute__ ((packed));
413 403
414/* REGISTER_LOCAL_ADDR IPA Command: ***************************************/
415/* TODO: define in analogy to commands define above */
416
417/* UNREGISTER_LOCAL_ADDR IPA Command: *************************************/
418/* TODO: define in analogy to commands define above */
419
420/* Header for each IPA command */ 404/* Header for each IPA command */
421struct qeth_ipacmd_hdr { 405struct qeth_ipacmd_hdr {
422 __u8 command; 406 __u8 command;
@@ -463,10 +447,8 @@ enum qeth_ipa_arp_return_codes {
463}; 447};
464 448
465 449
466extern char * 450extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
467qeth_get_ipa_msg(enum qeth_ipa_return_codes rc); 451extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
468extern char *
469qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
470 452
471#define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \ 453#define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
472 sizeof(struct qeth_ipacmd_setassparms_hdr)) 454 sizeof(struct qeth_ipacmd_setassparms_hdr))
@@ -492,88 +474,89 @@ extern unsigned char READ_CCW[];
492 474
493extern unsigned char CM_ENABLE[]; 475extern unsigned char CM_ENABLE[];
494#define CM_ENABLE_SIZE 0x63 476#define CM_ENABLE_SIZE 0x63
495#define QETH_CM_ENABLE_ISSUER_RM_TOKEN(buffer) (buffer+0x2c) 477#define QETH_CM_ENABLE_ISSUER_RM_TOKEN(buffer) (buffer + 0x2c)
496#define QETH_CM_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53) 478#define QETH_CM_ENABLE_FILTER_TOKEN(buffer) (buffer + 0x53)
497#define QETH_CM_ENABLE_USER_DATA(buffer) (buffer+0x5b) 479#define QETH_CM_ENABLE_USER_DATA(buffer) (buffer + 0x5b)
498 480
499#define QETH_CM_ENABLE_RESP_FILTER_TOKEN(buffer) \ 481#define QETH_CM_ENABLE_RESP_FILTER_TOKEN(buffer) \
500 (PDU_ENCAPSULATION(buffer)+ 0x13) 482 (PDU_ENCAPSULATION(buffer) + 0x13)
501 483
502 484
503extern unsigned char CM_SETUP[]; 485extern unsigned char CM_SETUP[];
504#define CM_SETUP_SIZE 0x64 486#define CM_SETUP_SIZE 0x64
505#define QETH_CM_SETUP_DEST_ADDR(buffer) (buffer+0x2c) 487#define QETH_CM_SETUP_DEST_ADDR(buffer) (buffer + 0x2c)
506#define QETH_CM_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51) 488#define QETH_CM_SETUP_CONNECTION_TOKEN(buffer) (buffer + 0x51)
507#define QETH_CM_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a) 489#define QETH_CM_SETUP_FILTER_TOKEN(buffer) (buffer + 0x5a)
508 490
509#define QETH_CM_SETUP_RESP_DEST_ADDR(buffer) \ 491#define QETH_CM_SETUP_RESP_DEST_ADDR(buffer) \
510 (PDU_ENCAPSULATION(buffer) + 0x1a) 492 (PDU_ENCAPSULATION(buffer) + 0x1a)
511 493
512extern unsigned char ULP_ENABLE[]; 494extern unsigned char ULP_ENABLE[];
513#define ULP_ENABLE_SIZE 0x6b 495#define ULP_ENABLE_SIZE 0x6b
514#define QETH_ULP_ENABLE_LINKNUM(buffer) (buffer+0x61) 496#define QETH_ULP_ENABLE_LINKNUM(buffer) (buffer + 0x61)
515#define QETH_ULP_ENABLE_DEST_ADDR(buffer) (buffer+0x2c) 497#define QETH_ULP_ENABLE_DEST_ADDR(buffer) (buffer + 0x2c)
516#define QETH_ULP_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53) 498#define QETH_ULP_ENABLE_FILTER_TOKEN(buffer) (buffer + 0x53)
517#define QETH_ULP_ENABLE_PORTNAME_AND_LL(buffer) (buffer+0x62) 499#define QETH_ULP_ENABLE_PORTNAME_AND_LL(buffer) (buffer + 0x62)
518#define QETH_ULP_ENABLE_RESP_FILTER_TOKEN(buffer) \ 500#define QETH_ULP_ENABLE_RESP_FILTER_TOKEN(buffer) \
519 (PDU_ENCAPSULATION(buffer) + 0x13) 501 (PDU_ENCAPSULATION(buffer) + 0x13)
520#define QETH_ULP_ENABLE_RESP_MAX_MTU(buffer) \ 502#define QETH_ULP_ENABLE_RESP_MAX_MTU(buffer) \
521 (PDU_ENCAPSULATION(buffer)+ 0x1f) 503 (PDU_ENCAPSULATION(buffer) + 0x1f)
522#define QETH_ULP_ENABLE_RESP_DIFINFO_LEN(buffer) \ 504#define QETH_ULP_ENABLE_RESP_DIFINFO_LEN(buffer) \
523 (PDU_ENCAPSULATION(buffer) + 0x17) 505 (PDU_ENCAPSULATION(buffer) + 0x17)
524#define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \ 506#define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \
525 (PDU_ENCAPSULATION(buffer)+ 0x2b) 507 (PDU_ENCAPSULATION(buffer) + 0x2b)
526/* Layer 2 defintions */ 508/* Layer 2 defintions */
527#define QETH_PROT_LAYER2 0x08 509#define QETH_PROT_LAYER2 0x08
528#define QETH_PROT_TCPIP 0x03 510#define QETH_PROT_TCPIP 0x03
529#define QETH_PROT_OSN2 0x0a 511#define QETH_PROT_OSN2 0x0a
530#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50) 512#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer + 0x50)
531#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19) 513#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer + 0x19)
532 514
533extern unsigned char ULP_SETUP[]; 515extern unsigned char ULP_SETUP[];
534#define ULP_SETUP_SIZE 0x6c 516#define ULP_SETUP_SIZE 0x6c
535#define QETH_ULP_SETUP_DEST_ADDR(buffer) (buffer+0x2c) 517#define QETH_ULP_SETUP_DEST_ADDR(buffer) (buffer + 0x2c)
536#define QETH_ULP_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51) 518#define QETH_ULP_SETUP_CONNECTION_TOKEN(buffer) (buffer + 0x51)
537#define QETH_ULP_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a) 519#define QETH_ULP_SETUP_FILTER_TOKEN(buffer) (buffer + 0x5a)
538#define QETH_ULP_SETUP_CUA(buffer) (buffer+0x68) 520#define QETH_ULP_SETUP_CUA(buffer) (buffer + 0x68)
539#define QETH_ULP_SETUP_REAL_DEVADDR(buffer) (buffer+0x6a) 521#define QETH_ULP_SETUP_REAL_DEVADDR(buffer) (buffer + 0x6a)
540 522
541#define QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(buffer) \ 523#define QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(buffer) \
542 (PDU_ENCAPSULATION(buffer)+0x1a) 524 (PDU_ENCAPSULATION(buffer) + 0x1a)
543 525
544 526
545extern unsigned char DM_ACT[]; 527extern unsigned char DM_ACT[];
546#define DM_ACT_SIZE 0x55 528#define DM_ACT_SIZE 0x55
547#define QETH_DM_ACT_DEST_ADDR(buffer) (buffer+0x2c) 529#define QETH_DM_ACT_DEST_ADDR(buffer) (buffer + 0x2c)
548#define QETH_DM_ACT_CONNECTION_TOKEN(buffer) (buffer+0x51) 530#define QETH_DM_ACT_CONNECTION_TOKEN(buffer) (buffer + 0x51)
549 531
550 532
551 533
552#define QETH_TRANSPORT_HEADER_SEQ_NO(buffer) (buffer+4) 534#define QETH_TRANSPORT_HEADER_SEQ_NO(buffer) (buffer + 4)
553#define QETH_PDU_HEADER_SEQ_NO(buffer) (buffer+0x1c) 535#define QETH_PDU_HEADER_SEQ_NO(buffer) (buffer + 0x1c)
554#define QETH_PDU_HEADER_ACK_SEQ_NO(buffer) (buffer+0x20) 536#define QETH_PDU_HEADER_ACK_SEQ_NO(buffer) (buffer + 0x20)
555 537
556extern unsigned char IDX_ACTIVATE_READ[]; 538extern unsigned char IDX_ACTIVATE_READ[];
557extern unsigned char IDX_ACTIVATE_WRITE[]; 539extern unsigned char IDX_ACTIVATE_WRITE[];
558 540
559#define IDX_ACTIVATE_SIZE 0x22 541#define IDX_ACTIVATE_SIZE 0x22
560#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c) 542#define QETH_IDX_ACT_PNO(buffer) (buffer+0x0b)
561#define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80) 543#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer + 0x0c)
562#define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10) 544#define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b] & 0x80)
563#define QETH_IDX_ACT_DATASET_NAME(buffer) (buffer+0x16) 545#define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer + 0x10)
564#define QETH_IDX_ACT_QDIO_DEV_CUA(buffer) (buffer+0x1e) 546#define QETH_IDX_ACT_DATASET_NAME(buffer) (buffer + 0x16)
565#define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer+0x20) 547#define QETH_IDX_ACT_QDIO_DEV_CUA(buffer) (buffer + 0x1e)
566#define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08]&3)==2) 548#define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer + 0x20)
567#define QETH_IDX_REPLY_LEVEL(buffer) (buffer+0x12) 549#define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08] & 3) == 2)
550#define QETH_IDX_REPLY_LEVEL(buffer) (buffer + 0x12)
568#define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09] 551#define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09]
569 552
570#define PDU_ENCAPSULATION(buffer) \ 553#define PDU_ENCAPSULATION(buffer) \
571 (buffer + *(buffer + (*(buffer+0x0b)) + \ 554 (buffer + *(buffer + (*(buffer + 0x0b)) + \
572 *(buffer + *(buffer+0x0b)+0x11) +0x07)) 555 *(buffer + *(buffer + 0x0b) + 0x11) + 0x07))
573 556
574#define IS_IPA(buffer) \ 557#define IS_IPA(buffer) \
575 ((buffer) && \ 558 ((buffer) && \
576 ( *(buffer + ((*(buffer+0x0b))+4) )==0xc1) ) 559 (*(buffer + ((*(buffer + 0x0b)) + 4)) == 0xc1))
577 560
578#define ADDR_FRAME_TYPE_DIX 1 561#define ADDR_FRAME_TYPE_DIX 1
579#define ADDR_FRAME_TYPE_802_3 2 562#define ADDR_FRAME_TYPE_802_3 2
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_core_offl.c
index e3c268cfbffe..8b407d6a83cf 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_core_offl.c
@@ -1,13 +1,11 @@
1/* 1/*
2 * linux/drivers/s390/net/qeth_eddp.c 2 * drivers/s390/net/qeth_core_offl.c
3 *
4 * Enhanced Device Driver Packing (EDDP) support for the qeth driver.
5 *
6 * Copyright 2004 IBM Corporation
7 *
8 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
9 * 3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Thomas Spatzier <tspat@de.ibm.com>,
6 * Frank Blaschka <frank.blaschka@de.ibm.com>
10 */ 7 */
8
11#include <linux/errno.h> 9#include <linux/errno.h>
12#include <linux/ip.h> 10#include <linux/ip.h>
13#include <linux/inetdevice.h> 11#include <linux/inetdevice.h>
@@ -18,14 +16,14 @@
18#include <linux/skbuff.h> 16#include <linux/skbuff.h>
19 17
20#include <net/ip.h> 18#include <net/ip.h>
19#include <net/ip6_checksum.h>
21 20
22#include "qeth.h" 21#include "qeth_core.h"
23#include "qeth_mpc.h" 22#include "qeth_core_mpc.h"
24#include "qeth_eddp.h" 23#include "qeth_core_offl.h"
25 24
26int 25int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
27qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue, 26 struct qeth_eddp_context *ctx)
28 struct qeth_eddp_context *ctx)
29{ 27{
30 int index = queue->next_buf_to_fill; 28 int index = queue->next_buf_to_fill;
31 int elements_needed = ctx->num_elements; 29 int elements_needed = ctx->num_elements;
@@ -34,7 +32,7 @@ qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
34 int buffers_needed = 0; 32 int buffers_needed = 0;
35 33
36 QETH_DBF_TEXT(trace, 5, "eddpcbfc"); 34 QETH_DBF_TEXT(trace, 5, "eddpcbfc");
37 while(elements_needed > 0) { 35 while (elements_needed > 0) {
38 buffers_needed++; 36 buffers_needed++;
39 if (atomic_read(&queue->bufs[index].state) != 37 if (atomic_read(&queue->bufs[index].state) !=
40 QETH_QDIO_BUF_EMPTY) 38 QETH_QDIO_BUF_EMPTY)
@@ -49,8 +47,7 @@ qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
49 return buffers_needed; 47 return buffers_needed;
50} 48}
51 49
52static void 50static void qeth_eddp_free_context(struct qeth_eddp_context *ctx)
53qeth_eddp_free_context(struct qeth_eddp_context *ctx)
54{ 51{
55 int i; 52 int i;
56 53
@@ -63,26 +60,24 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx)
63} 60}
64 61
65 62
66static inline void 63static void qeth_eddp_get_context(struct qeth_eddp_context *ctx)
67qeth_eddp_get_context(struct qeth_eddp_context *ctx)
68{ 64{
69 atomic_inc(&ctx->refcnt); 65 atomic_inc(&ctx->refcnt);
70} 66}
71 67
72void 68void qeth_eddp_put_context(struct qeth_eddp_context *ctx)
73qeth_eddp_put_context(struct qeth_eddp_context *ctx)
74{ 69{
75 if (atomic_dec_return(&ctx->refcnt) == 0) 70 if (atomic_dec_return(&ctx->refcnt) == 0)
76 qeth_eddp_free_context(ctx); 71 qeth_eddp_free_context(ctx);
77} 72}
73EXPORT_SYMBOL_GPL(qeth_eddp_put_context);
78 74
79void 75void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
80qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
81{ 76{
82 struct qeth_eddp_context_reference *ref; 77 struct qeth_eddp_context_reference *ref;
83 78
84 QETH_DBF_TEXT(trace, 6, "eddprctx"); 79 QETH_DBF_TEXT(trace, 6, "eddprctx");
85 while (!list_empty(&buf->ctx_list)){ 80 while (!list_empty(&buf->ctx_list)) {
86 ref = list_entry(buf->ctx_list.next, 81 ref = list_entry(buf->ctx_list.next,
87 struct qeth_eddp_context_reference, list); 82 struct qeth_eddp_context_reference, list);
88 qeth_eddp_put_context(ref->ctx); 83 qeth_eddp_put_context(ref->ctx);
@@ -91,9 +86,8 @@ qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
91 } 86 }
92} 87}
93 88
94static int 89static int qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
95qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf, 90 struct qeth_eddp_context *ctx)
96 struct qeth_eddp_context *ctx)
97{ 91{
98 struct qeth_eddp_context_reference *ref; 92 struct qeth_eddp_context_reference *ref;
99 93
@@ -107,10 +101,8 @@ qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
107 return 0; 101 return 0;
108} 102}
109 103
110int 104int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
111qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, 105 struct qeth_eddp_context *ctx, int index)
112 struct qeth_eddp_context *ctx,
113 int index)
114{ 106{
115 struct qeth_qdio_out_buffer *buf = NULL; 107 struct qeth_qdio_out_buffer *buf = NULL;
116 struct qdio_buffer *buffer; 108 struct qdio_buffer *buffer;
@@ -123,7 +115,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
123 QETH_DBF_TEXT(trace, 5, "eddpfibu"); 115 QETH_DBF_TEXT(trace, 5, "eddpfibu");
124 while (elements > 0) { 116 while (elements > 0) {
125 buf = &queue->bufs[index]; 117 buf = &queue->bufs[index];
126 if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY){ 118 if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY) {
127 /* normally this should not happen since we checked for 119 /* normally this should not happen since we checked for
128 * available elements in qeth_check_elements_for_context 120 * available elements in qeth_check_elements_for_context
129 */ 121 */
@@ -148,9 +140,9 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
148 must_refcnt = 1; 140 must_refcnt = 1;
149 continue; 141 continue;
150 } 142 }
151 if (must_refcnt){ 143 if (must_refcnt) {
152 must_refcnt = 0; 144 must_refcnt = 0;
153 if (qeth_eddp_buf_ref_context(buf, ctx)){ 145 if (qeth_eddp_buf_ref_context(buf, ctx)) {
154 PRINT_WARN("no memory to create eddp context " 146 PRINT_WARN("no memory to create eddp context "
155 "reference\n"); 147 "reference\n");
156 goto out_check; 148 goto out_check;
@@ -158,7 +150,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
158 } 150 }
159 buffer = buf->buffer; 151 buffer = buf->buffer;
160 /* fill one skb into buffer */ 152 /* fill one skb into buffer */
161 for (i = 0; i < ctx->elements_per_skb; ++i){ 153 for (i = 0; i < ctx->elements_per_skb; ++i) {
162 if (ctx->elements[element].length != 0) { 154 if (ctx->elements[element].length != 0) {
163 buffer->element[buf->next_element_to_fill]. 155 buffer->element[buf->next_element_to_fill].
164 addr = ctx->elements[element].addr; 156 addr = ctx->elements[element].addr;
@@ -176,7 +168,7 @@ out_check:
176 if (!queue->do_pack) { 168 if (!queue->do_pack) {
177 QETH_DBF_TEXT(trace, 6, "fillbfnp"); 169 QETH_DBF_TEXT(trace, 6, "fillbfnp");
178 /* set state to PRIMED -> will be flushed */ 170 /* set state to PRIMED -> will be flushed */
179 if (buf->next_element_to_fill > 0){ 171 if (buf->next_element_to_fill > 0) {
180 atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED); 172 atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
181 flush_cnt++; 173 flush_cnt++;
182 } 174 }
@@ -198,9 +190,8 @@ out:
198 return flush_cnt; 190 return flush_cnt;
199} 191}
200 192
201static void 193static void qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
202qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx, 194 struct qeth_eddp_data *eddp, int data_len)
203 struct qeth_eddp_data *eddp, int data_len)
204{ 195{
205 u8 *page; 196 u8 *page;
206 int page_remainder; 197 int page_remainder;
@@ -220,7 +211,7 @@ qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
220 pkt_len += VLAN_HLEN; 211 pkt_len += VLAN_HLEN;
221 /* does complete packet fit in current page ? */ 212 /* does complete packet fit in current page ? */
222 page_remainder = PAGE_SIZE - page_offset; 213 page_remainder = PAGE_SIZE - page_offset;
223 if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){ 214 if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)) {
224 /* no -> go to start of next page */ 215 /* no -> go to start of next page */
225 ctx->offset += page_remainder; 216 ctx->offset += page_remainder;
226 page = ctx->pages[ctx->offset >> PAGE_SHIFT]; 217 page = ctx->pages[ctx->offset >> PAGE_SHIFT];
@@ -232,14 +223,14 @@ qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
232 ctx->offset += sizeof(struct qeth_hdr); 223 ctx->offset += sizeof(struct qeth_hdr);
233 page_offset += sizeof(struct qeth_hdr); 224 page_offset += sizeof(struct qeth_hdr);
234 /* add mac header (?) */ 225 /* add mac header (?) */
235 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ 226 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
236 memcpy(page + page_offset, &eddp->mac, ETH_HLEN); 227 memcpy(page + page_offset, &eddp->mac, ETH_HLEN);
237 element->length += ETH_HLEN; 228 element->length += ETH_HLEN;
238 ctx->offset += ETH_HLEN; 229 ctx->offset += ETH_HLEN;
239 page_offset += ETH_HLEN; 230 page_offset += ETH_HLEN;
240 } 231 }
241 /* add VLAN tag */ 232 /* add VLAN tag */
242 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)){ 233 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
243 memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN); 234 memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN);
244 element->length += VLAN_HLEN; 235 element->length += VLAN_HLEN;
245 ctx->offset += VLAN_HLEN; 236 ctx->offset += VLAN_HLEN;
@@ -258,9 +249,8 @@ qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
258 ctx->offset += eddp->thl; 249 ctx->offset += eddp->thl;
259} 250}
260 251
261static void 252static void qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp,
262qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len, 253 int len, __wsum *hcsum)
263 __wsum *hcsum)
264{ 254{
265 struct skb_frag_struct *frag; 255 struct skb_frag_struct *frag;
266 int left_in_frag; 256 int left_in_frag;
@@ -278,16 +268,17 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
278 while (len > 0) { 268 while (len > 0) {
279 if (eddp->frag < 0) { 269 if (eddp->frag < 0) {
280 /* we're in skb->data */ 270 /* we're in skb->data */
281 left_in_frag = (eddp->skb->len - eddp->skb->data_len) 271 left_in_frag = (eddp->skb->len -
272 eddp->skb->data_len)
282 - eddp->skb_offset; 273 - eddp->skb_offset;
283 src = eddp->skb->data + eddp->skb_offset; 274 src = eddp->skb->data + eddp->skb_offset;
284 } else { 275 } else {
285 frag = &skb_shinfo(eddp->skb)-> 276 frag = &skb_shinfo(eddp->skb)->frags[
286 frags[eddp->frag]; 277 eddp->frag];
287 left_in_frag = frag->size - eddp->frag_offset; 278 left_in_frag = frag->size - eddp->frag_offset;
288 src = (u8 *)( 279 src = (u8 *)((page_to_pfn(frag->page) <<
289 (page_to_pfn(frag->page) << PAGE_SHIFT)+ 280 PAGE_SHIFT) + frag->page_offset +
290 frag->page_offset + eddp->frag_offset); 281 eddp->frag_offset);
291 } 282 }
292 if (left_in_frag <= 0) { 283 if (left_in_frag <= 0) {
293 eddp->frag++; 284 eddp->frag++;
@@ -305,10 +296,8 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
305 } 296 }
306} 297}
307 298
308static void 299static void qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
309qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx, 300 struct qeth_eddp_data *eddp, int data_len, __wsum hcsum)
310 struct qeth_eddp_data *eddp, int data_len,
311 __wsum hcsum)
312{ 301{
313 u8 *page; 302 u8 *page;
314 int page_remainder; 303 int page_remainder;
@@ -320,9 +309,9 @@ qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
320 page = ctx->pages[ctx->offset >> PAGE_SHIFT]; 309 page = ctx->pages[ctx->offset >> PAGE_SHIFT];
321 page_offset = ctx->offset % PAGE_SIZE; 310 page_offset = ctx->offset % PAGE_SIZE;
322 element = &ctx->elements[ctx->num_elements]; 311 element = &ctx->elements[ctx->num_elements];
323 while (data_len){ 312 while (data_len) {
324 page_remainder = PAGE_SIZE - page_offset; 313 page_remainder = PAGE_SIZE - page_offset;
325 if (page_remainder < data_len){ 314 if (page_remainder < data_len) {
326 qeth_eddp_copy_data_tcp(page + page_offset, eddp, 315 qeth_eddp_copy_data_tcp(page + page_offset, eddp,
327 page_remainder, &hcsum); 316 page_remainder, &hcsum);
328 element->length += page_remainder; 317 element->length += page_remainder;
@@ -352,8 +341,8 @@ qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
352 ((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum); 341 ((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
353} 342}
354 343
355static __wsum 344static __wsum qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp,
356qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len) 345 int data_len)
357{ 346{
358 __wsum phcsum; /* pseudo header checksum */ 347 __wsum phcsum; /* pseudo header checksum */
359 348
@@ -366,8 +355,8 @@ qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
366 return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum); 355 return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum);
367} 356}
368 357
369static __wsum 358static __wsum qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp,
370qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len) 359 int data_len)
371{ 360{
372 __be32 proto; 361 __be32 proto;
373 __wsum phcsum; /* pseudo header checksum */ 362 __wsum phcsum; /* pseudo header checksum */
@@ -384,14 +373,14 @@ qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
384 return phcsum; 373 return phcsum;
385} 374}
386 375
387static struct qeth_eddp_data * 376static struct qeth_eddp_data *qeth_eddp_create_eddp_data(struct qeth_hdr *qh,
388qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl) 377 u8 *nh, u8 nhl, u8 *th, u8 thl)
389{ 378{
390 struct qeth_eddp_data *eddp; 379 struct qeth_eddp_data *eddp;
391 380
392 QETH_DBF_TEXT(trace, 5, "eddpcrda"); 381 QETH_DBF_TEXT(trace, 5, "eddpcrda");
393 eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC); 382 eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC);
394 if (eddp){ 383 if (eddp) {
395 eddp->nhl = nhl; 384 eddp->nhl = nhl;
396 eddp->thl = thl; 385 eddp->thl = thl;
397 memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr)); 386 memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr));
@@ -402,9 +391,8 @@ qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
402 return eddp; 391 return eddp;
403} 392}
404 393
405static void 394static void __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
406__qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, 395 struct qeth_eddp_data *eddp)
407 struct qeth_eddp_data *eddp)
408{ 396{
409 struct tcphdr *tcph; 397 struct tcphdr *tcph;
410 int data_len; 398 int data_len;
@@ -412,30 +400,26 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
412 400
413 QETH_DBF_TEXT(trace, 5, "eddpftcp"); 401 QETH_DBF_TEXT(trace, 5, "eddpftcp");
414 eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; 402 eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
415 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { 403 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
416 eddp->skb_offset += sizeof(struct ethhdr); 404 eddp->skb_offset += sizeof(struct ethhdr);
417#ifdef CONFIG_QETH_VLAN 405 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
418 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) 406 eddp->skb_offset += VLAN_HLEN;
419 eddp->skb_offset += VLAN_HLEN; 407 }
420#endif /* CONFIG_QETH_VLAN */
421 }
422 tcph = tcp_hdr(eddp->skb); 408 tcph = tcp_hdr(eddp->skb);
423 while (eddp->skb_offset < eddp->skb->len) { 409 while (eddp->skb_offset < eddp->skb->len) {
424 data_len = min((int)skb_shinfo(eddp->skb)->gso_size, 410 data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
425 (int)(eddp->skb->len - eddp->skb_offset)); 411 (int)(eddp->skb->len - eddp->skb_offset));
426 /* prepare qdio hdr */ 412 /* prepare qdio hdr */
427 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ 413 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
428 eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN + 414 eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN +
429 eddp->nhl + eddp->thl; 415 eddp->nhl + eddp->thl;
430#ifdef CONFIG_QETH_VLAN
431 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) 416 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
432 eddp->qh.hdr.l2.pkt_length += VLAN_HLEN; 417 eddp->qh.hdr.l2.pkt_length += VLAN_HLEN;
433#endif /* CONFIG_QETH_VLAN */
434 } else 418 } else
435 eddp->qh.hdr.l3.length = data_len + eddp->nhl + 419 eddp->qh.hdr.l3.length = data_len + eddp->nhl +
436 eddp->thl; 420 eddp->thl;
437 /* prepare ip hdr */ 421 /* prepare ip hdr */
438 if (eddp->skb->protocol == htons(ETH_P_IP)){ 422 if (eddp->skb->protocol == htons(ETH_P_IP)) {
439 eddp->nh.ip4.h.tot_len = htons(data_len + eddp->nhl + 423 eddp->nh.ip4.h.tot_len = htons(data_len + eddp->nhl +
440 eddp->thl); 424 eddp->thl);
441 eddp->nh.ip4.h.check = 0; 425 eddp->nh.ip4.h.check = 0;
@@ -443,9 +427,10 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
443 ip_fast_csum((u8 *)&eddp->nh.ip4.h, 427 ip_fast_csum((u8 *)&eddp->nh.ip4.h,
444 eddp->nh.ip4.h.ihl); 428 eddp->nh.ip4.h.ihl);
445 } else 429 } else
446 eddp->nh.ip6.h.payload_len = htons(data_len + eddp->thl); 430 eddp->nh.ip6.h.payload_len = htons(data_len +
431 eddp->thl);
447 /* prepare tcp hdr */ 432 /* prepare tcp hdr */
448 if (data_len == (eddp->skb->len - eddp->skb_offset)){ 433 if (data_len == (eddp->skb->len - eddp->skb_offset)) {
449 /* last segment -> set FIN and PSH flags */ 434 /* last segment -> set FIN and PSH flags */
450 eddp->th.tcp.h.fin = tcph->fin; 435 eddp->th.tcp.h.fin = tcph->fin;
451 eddp->th.tcp.h.psh = tcph->psh; 436 eddp->th.tcp.h.psh = tcph->psh;
@@ -462,13 +447,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
462 /* prepare headers for next round */ 447 /* prepare headers for next round */
463 if (eddp->skb->protocol == htons(ETH_P_IP)) 448 if (eddp->skb->protocol == htons(ETH_P_IP))
464 eddp->nh.ip4.h.id = htons(ntohs(eddp->nh.ip4.h.id) + 1); 449 eddp->nh.ip4.h.id = htons(ntohs(eddp->nh.ip4.h.id) + 1);
465 eddp->th.tcp.h.seq = htonl(ntohl(eddp->th.tcp.h.seq) + data_len); 450 eddp->th.tcp.h.seq = htonl(ntohl(eddp->th.tcp.h.seq) +
451 data_len);
466 } 452 }
467} 453}
468 454
469static int 455static int qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
470qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, 456 struct sk_buff *skb, struct qeth_hdr *qhdr)
471 struct sk_buff *skb, struct qeth_hdr *qhdr)
472{ 457{
473 struct qeth_eddp_data *eddp = NULL; 458 struct qeth_eddp_data *eddp = NULL;
474 459
@@ -494,12 +479,10 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
494 if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { 479 if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
495 skb_set_mac_header(skb, sizeof(struct qeth_hdr)); 480 skb_set_mac_header(skb, sizeof(struct qeth_hdr));
496 memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN); 481 memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
497#ifdef CONFIG_QETH_VLAN
498 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) { 482 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
499 eddp->vlan[0] = skb->protocol; 483 eddp->vlan[0] = skb->protocol;
500 eddp->vlan[1] = htons(vlan_tx_tag_get(skb)); 484 eddp->vlan[1] = htons(vlan_tx_tag_get(skb));
501 } 485 }
502#endif /* CONFIG_QETH_VLAN */
503 } 486 }
504 /* the next flags will only be set on the last segment */ 487 /* the next flags will only be set on the last segment */
505 eddp->th.tcp.h.fin = 0; 488 eddp->th.tcp.h.fin = 0;
@@ -511,16 +494,15 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
511 return 0; 494 return 0;
512} 495}
513 496
514static void 497static void qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx,
515qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb, 498 struct sk_buff *skb, int hdr_len)
516 int hdr_len)
517{ 499{
518 int skbs_per_page; 500 int skbs_per_page;
519 501
520 QETH_DBF_TEXT(trace, 5, "eddpcanp"); 502 QETH_DBF_TEXT(trace, 5, "eddpcanp");
521 /* can we put multiple skbs in one page? */ 503 /* can we put multiple skbs in one page? */
522 skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len); 504 skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
523 if (skbs_per_page > 1){ 505 if (skbs_per_page > 1) {
524 ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) / 506 ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
525 skbs_per_page + 1; 507 skbs_per_page + 1;
526 ctx->elements_per_skb = 1; 508 ctx->elements_per_skb = 1;
@@ -535,9 +517,8 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
535 (skb_shinfo(skb)->gso_segs + 1); 517 (skb_shinfo(skb)->gso_segs + 1);
536} 518}
537 519
538static struct qeth_eddp_context * 520static struct qeth_eddp_context *qeth_eddp_create_context_generic(
539qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb, 521 struct qeth_card *card, struct sk_buff *skb, int hdr_len)
540 int hdr_len)
541{ 522{
542 struct qeth_eddp_context *ctx = NULL; 523 struct qeth_eddp_context *ctx = NULL;
543 u8 *addr; 524 u8 *addr;
@@ -546,37 +527,36 @@ qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
546 QETH_DBF_TEXT(trace, 5, "creddpcg"); 527 QETH_DBF_TEXT(trace, 5, "creddpcg");
547 /* create the context and allocate pages */ 528 /* create the context and allocate pages */
548 ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC); 529 ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC);
549 if (ctx == NULL){ 530 if (ctx == NULL) {
550 QETH_DBF_TEXT(trace, 2, "ceddpcn1"); 531 QETH_DBF_TEXT(trace, 2, "ceddpcn1");
551 return NULL; 532 return NULL;
552 } 533 }
553 ctx->type = QETH_LARGE_SEND_EDDP; 534 ctx->type = QETH_LARGE_SEND_EDDP;
554 qeth_eddp_calc_num_pages(ctx, skb, hdr_len); 535 qeth_eddp_calc_num_pages(ctx, skb, hdr_len);
555 if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)){ 536 if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)) {
556 QETH_DBF_TEXT(trace, 2, "ceddpcis"); 537 QETH_DBF_TEXT(trace, 2, "ceddpcis");
557 kfree(ctx); 538 kfree(ctx);
558 return NULL; 539 return NULL;
559 } 540 }
560 ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC); 541 ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC);
561 if (ctx->pages == NULL){ 542 if (ctx->pages == NULL) {
562 QETH_DBF_TEXT(trace, 2, "ceddpcn2"); 543 QETH_DBF_TEXT(trace, 2, "ceddpcn2");
563 kfree(ctx); 544 kfree(ctx);
564 return NULL; 545 return NULL;
565 } 546 }
566 for (i = 0; i < ctx->num_pages; ++i){ 547 for (i = 0; i < ctx->num_pages; ++i) {
567 addr = (u8 *)__get_free_page(GFP_ATOMIC); 548 addr = (u8 *)get_zeroed_page(GFP_ATOMIC);
568 if (addr == NULL){ 549 if (addr == NULL) {
569 QETH_DBF_TEXT(trace, 2, "ceddpcn3"); 550 QETH_DBF_TEXT(trace, 2, "ceddpcn3");
570 ctx->num_pages = i; 551 ctx->num_pages = i;
571 qeth_eddp_free_context(ctx); 552 qeth_eddp_free_context(ctx);
572 return NULL; 553 return NULL;
573 } 554 }
574 memset(addr, 0, PAGE_SIZE);
575 ctx->pages[i] = addr; 555 ctx->pages[i] = addr;
576 } 556 }
577 ctx->elements = kcalloc(ctx->num_elements, 557 ctx->elements = kcalloc(ctx->num_elements,
578 sizeof(struct qeth_eddp_element), GFP_ATOMIC); 558 sizeof(struct qeth_eddp_element), GFP_ATOMIC);
579 if (ctx->elements == NULL){ 559 if (ctx->elements == NULL) {
580 QETH_DBF_TEXT(trace, 2, "ceddpcn4"); 560 QETH_DBF_TEXT(trace, 2, "ceddpcn4");
581 qeth_eddp_free_context(ctx); 561 qeth_eddp_free_context(ctx);
582 return NULL; 562 return NULL;
@@ -587,18 +567,18 @@ qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
587 return ctx; 567 return ctx;
588} 568}
589 569
590static struct qeth_eddp_context * 570static struct qeth_eddp_context *qeth_eddp_create_context_tcp(
591qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb, 571 struct qeth_card *card, struct sk_buff *skb,
592 struct qeth_hdr *qhdr) 572 struct qeth_hdr *qhdr)
593{ 573{
594 struct qeth_eddp_context *ctx = NULL; 574 struct qeth_eddp_context *ctx = NULL;
595 575
596 QETH_DBF_TEXT(trace, 5, "creddpct"); 576 QETH_DBF_TEXT(trace, 5, "creddpct");
597 if (skb->protocol == htons(ETH_P_IP)) 577 if (skb->protocol == htons(ETH_P_IP))
598 ctx = qeth_eddp_create_context_generic(card, skb, 578 ctx = qeth_eddp_create_context_generic(card, skb,
599 (sizeof(struct qeth_hdr) + 579 (sizeof(struct qeth_hdr) +
600 ip_hdrlen(skb) + 580 ip_hdrlen(skb) +
601 tcp_hdrlen(skb))); 581 tcp_hdrlen(skb)));
602 else if (skb->protocol == htons(ETH_P_IPV6)) 582 else if (skb->protocol == htons(ETH_P_IPV6))
603 ctx = qeth_eddp_create_context_generic(card, skb, 583 ctx = qeth_eddp_create_context_generic(card, skb,
604 sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) + 584 sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) +
@@ -610,7 +590,7 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
610 QETH_DBF_TEXT(trace, 2, "creddpnl"); 590 QETH_DBF_TEXT(trace, 2, "creddpnl");
611 return NULL; 591 return NULL;
612 } 592 }
613 if (qeth_eddp_fill_context_tcp(ctx, skb, qhdr)){ 593 if (qeth_eddp_fill_context_tcp(ctx, skb, qhdr)) {
614 QETH_DBF_TEXT(trace, 2, "ceddptfe"); 594 QETH_DBF_TEXT(trace, 2, "ceddptfe");
615 qeth_eddp_free_context(ctx); 595 qeth_eddp_free_context(ctx);
616 return NULL; 596 return NULL;
@@ -619,9 +599,9 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
619 return ctx; 599 return ctx;
620} 600}
621 601
622struct qeth_eddp_context * 602struct qeth_eddp_context *qeth_eddp_create_context(struct qeth_card *card,
623qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb, 603 struct sk_buff *skb, struct qeth_hdr *qhdr,
624 struct qeth_hdr *qhdr, unsigned char sk_protocol) 604 unsigned char sk_protocol)
625{ 605{
626 QETH_DBF_TEXT(trace, 5, "creddpc"); 606 QETH_DBF_TEXT(trace, 5, "creddpc");
627 switch (sk_protocol) { 607 switch (sk_protocol) {
@@ -632,3 +612,90 @@ qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
632 } 612 }
633 return NULL; 613 return NULL;
634} 614}
615EXPORT_SYMBOL_GPL(qeth_eddp_create_context);
616
617void qeth_tso_fill_header(struct qeth_card *card, struct qeth_hdr *qhdr,
618 struct sk_buff *skb)
619{
620 struct qeth_hdr_tso *hdr = (struct qeth_hdr_tso *)qhdr;
621 struct tcphdr *tcph = tcp_hdr(skb);
622 struct iphdr *iph = ip_hdr(skb);
623 struct ipv6hdr *ip6h = ipv6_hdr(skb);
624
625 QETH_DBF_TEXT(trace, 5, "tsofhdr");
626
627 /*fix header to TSO values ...*/
628 hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
629 /*set values which are fix for the first approach ...*/
630 hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
631 hdr->ext.imb_hdr_no = 1;
632 hdr->ext.hdr_type = 1;
633 hdr->ext.hdr_version = 1;
634 hdr->ext.hdr_len = 28;
635 /*insert non-fix values */
636 hdr->ext.mss = skb_shinfo(skb)->gso_size;
637 hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
638 hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
639 sizeof(struct qeth_hdr_tso));
640 tcph->check = 0;
641 if (skb->protocol == ETH_P_IPV6) {
642 ip6h->payload_len = 0;
643 tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
644 0, IPPROTO_TCP, 0);
645 } else {
646 /*OSA want us to set these values ...*/
647 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
648 0, IPPROTO_TCP, 0);
649 iph->tot_len = 0;
650 iph->check = 0;
651 }
652}
653EXPORT_SYMBOL_GPL(qeth_tso_fill_header);
654
655void qeth_tx_csum(struct sk_buff *skb)
656{
657 int tlen;
658 if (skb->protocol == htons(ETH_P_IP)) {
659 tlen = ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2);
660 switch (ip_hdr(skb)->protocol) {
661 case IPPROTO_TCP:
662 tcp_hdr(skb)->check = 0;
663 tcp_hdr(skb)->check = csum_tcpudp_magic(
664 ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
665 tlen, ip_hdr(skb)->protocol,
666 skb_checksum(skb, skb_transport_offset(skb),
667 tlen, 0));
668 break;
669 case IPPROTO_UDP:
670 udp_hdr(skb)->check = 0;
671 udp_hdr(skb)->check = csum_tcpudp_magic(
672 ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
673 tlen, ip_hdr(skb)->protocol,
674 skb_checksum(skb, skb_transport_offset(skb),
675 tlen, 0));
676 break;
677 }
678 } else if (skb->protocol == htons(ETH_P_IPV6)) {
679 switch (ipv6_hdr(skb)->nexthdr) {
680 case IPPROTO_TCP:
681 tcp_hdr(skb)->check = 0;
682 tcp_hdr(skb)->check = csum_ipv6_magic(
683 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
684 ipv6_hdr(skb)->payload_len,
685 ipv6_hdr(skb)->nexthdr,
686 skb_checksum(skb, skb_transport_offset(skb),
687 ipv6_hdr(skb)->payload_len, 0));
688 break;
689 case IPPROTO_UDP:
690 udp_hdr(skb)->check = 0;
691 udp_hdr(skb)->check = csum_ipv6_magic(
692 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
693 ipv6_hdr(skb)->payload_len,
694 ipv6_hdr(skb)->nexthdr,
695 skb_checksum(skb, skb_transport_offset(skb),
696 ipv6_hdr(skb)->payload_len, 0));
697 break;
698 }
699 }
700}
701EXPORT_SYMBOL_GPL(qeth_tx_csum);
diff --git a/drivers/s390/net/qeth_eddp.h b/drivers/s390/net/qeth_core_offl.h
index 52910c9252c0..86bf7df8cf16 100644
--- a/drivers/s390/net/qeth_eddp.h
+++ b/drivers/s390/net/qeth_core_offl.h
@@ -1,15 +1,13 @@
1/* 1/*
2 * linux/drivers/s390/net/qeth_eddp.h 2 * drivers/s390/net/qeth_core_offl.h
3 *
4 * Header file for qeth enhanced device driver packing.
5 *
6 * Copyright 2004 IBM Corporation
7 *
8 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
9 * 3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Thomas Spatzier <tspat@de.ibm.com>,
6 * Frank Blaschka <frank.blaschka@de.ibm.com>
10 */ 7 */
11#ifndef __QETH_EDDP_H__ 8
12#define __QETH_EDDP_H__ 9#ifndef __QETH_CORE_OFFL_H__
10#define __QETH_CORE_OFFL_H__
13 11
14struct qeth_eddp_element { 12struct qeth_eddp_element {
15 u32 flags; 13 u32 flags;
@@ -33,25 +31,6 @@ struct qeth_eddp_context_reference {
33 struct qeth_eddp_context *ctx; 31 struct qeth_eddp_context *ctx;
34}; 32};
35 33
36extern struct qeth_eddp_context *
37qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,
38 struct qeth_hdr *, unsigned char);
39
40extern void
41qeth_eddp_put_context(struct qeth_eddp_context *);
42
43extern int
44qeth_eddp_fill_buffer(struct qeth_qdio_out_q *,struct qeth_eddp_context *,int);
45
46extern void
47qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *);
48
49extern int
50qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
51 struct qeth_eddp_context *);
52/*
53 * Data used for fragmenting a IP packet.
54 */
55struct qeth_eddp_data { 34struct qeth_eddp_data {
56 struct qeth_hdr qh; 35 struct qeth_hdr qh;
57 struct ethhdr mac; 36 struct ethhdr mac;
@@ -81,4 +60,17 @@ struct qeth_eddp_data {
81 int frag_offset; 60 int frag_offset;
82} __attribute__ ((packed)); 61} __attribute__ ((packed));
83 62
84#endif /* __QETH_EDDP_H__ */ 63extern struct qeth_eddp_context *qeth_eddp_create_context(struct qeth_card *,
64 struct sk_buff *, struct qeth_hdr *, unsigned char);
65extern void qeth_eddp_put_context(struct qeth_eddp_context *);
66extern int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *,
67 struct qeth_eddp_context *, int);
68extern void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *);
69extern int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
70 struct qeth_eddp_context *);
71
72void qeth_tso_fill_header(struct qeth_card *, struct qeth_hdr *,
73 struct sk_buff *);
74void qeth_tx_csum(struct sk_buff *skb);
75
76#endif /* __QETH_CORE_EDDP_H__ */
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
new file mode 100644
index 000000000000..08a50f057284
--- /dev/null
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -0,0 +1,651 @@
1/*
2 * drivers/s390/net/qeth_core_sys.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
11#include <linux/list.h>
12#include <linux/rwsem.h>
13#include <asm/ebcdic.h>
14
15#include "qeth_core.h"
16
17static ssize_t qeth_dev_state_show(struct device *dev,
18 struct device_attribute *attr, char *buf)
19{
20 struct qeth_card *card = dev_get_drvdata(dev);
21 if (!card)
22 return -EINVAL;
23
24 switch (card->state) {
25 case CARD_STATE_DOWN:
26 return sprintf(buf, "DOWN\n");
27 case CARD_STATE_HARDSETUP:
28 return sprintf(buf, "HARDSETUP\n");
29 case CARD_STATE_SOFTSETUP:
30 return sprintf(buf, "SOFTSETUP\n");
31 case CARD_STATE_UP:
32 if (card->lan_online)
33 return sprintf(buf, "UP (LAN ONLINE)\n");
34 else
35 return sprintf(buf, "UP (LAN OFFLINE)\n");
36 case CARD_STATE_RECOVER:
37 return sprintf(buf, "RECOVER\n");
38 default:
39 return sprintf(buf, "UNKNOWN\n");
40 }
41}
42
43static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
44
45static ssize_t qeth_dev_chpid_show(struct device *dev,
46 struct device_attribute *attr, char *buf)
47{
48 struct qeth_card *card = dev_get_drvdata(dev);
49 if (!card)
50 return -EINVAL;
51
52 return sprintf(buf, "%02X\n", card->info.chpid);
53}
54
55static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
56
57static ssize_t qeth_dev_if_name_show(struct device *dev,
58 struct device_attribute *attr, char *buf)
59{
60 struct qeth_card *card = dev_get_drvdata(dev);
61 if (!card)
62 return -EINVAL;
63 return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));
64}
65
66static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
67
68static ssize_t qeth_dev_card_type_show(struct device *dev,
69 struct device_attribute *attr, char *buf)
70{
71 struct qeth_card *card = dev_get_drvdata(dev);
72 if (!card)
73 return -EINVAL;
74
75 return sprintf(buf, "%s\n", qeth_get_cardname_short(card));
76}
77
78static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
79
80static inline const char *qeth_get_bufsize_str(struct qeth_card *card)
81{
82 if (card->qdio.in_buf_size == 16384)
83 return "16k";
84 else if (card->qdio.in_buf_size == 24576)
85 return "24k";
86 else if (card->qdio.in_buf_size == 32768)
87 return "32k";
88 else if (card->qdio.in_buf_size == 40960)
89 return "40k";
90 else
91 return "64k";
92}
93
94static ssize_t qeth_dev_inbuf_size_show(struct device *dev,
95 struct device_attribute *attr, char *buf)
96{
97 struct qeth_card *card = dev_get_drvdata(dev);
98 if (!card)
99 return -EINVAL;
100
101 return sprintf(buf, "%s\n", qeth_get_bufsize_str(card));
102}
103
104static DEVICE_ATTR(inbuf_size, 0444, qeth_dev_inbuf_size_show, NULL);
105
106static ssize_t qeth_dev_portno_show(struct device *dev,
107 struct device_attribute *attr, char *buf)
108{
109 struct qeth_card *card = dev_get_drvdata(dev);
110 if (!card)
111 return -EINVAL;
112
113 return sprintf(buf, "%i\n", card->info.portno);
114}
115
116static ssize_t qeth_dev_portno_store(struct device *dev,
117 struct device_attribute *attr, const char *buf, size_t count)
118{
119 struct qeth_card *card = dev_get_drvdata(dev);
120 char *tmp;
121 unsigned int portno;
122
123 if (!card)
124 return -EINVAL;
125
126 if ((card->state != CARD_STATE_DOWN) &&
127 (card->state != CARD_STATE_RECOVER))
128 return -EPERM;
129
130 portno = simple_strtoul(buf, &tmp, 16);
131 if (portno > QETH_MAX_PORTNO) {
132 PRINT_WARN("portno 0x%X is out of range\n", portno);
133 return -EINVAL;
134 }
135
136 card->info.portno = portno;
137 return count;
138}
139
140static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
141
142static ssize_t qeth_dev_portname_show(struct device *dev,
143 struct device_attribute *attr, char *buf)
144{
145 struct qeth_card *card = dev_get_drvdata(dev);
146 char portname[9] = {0, };
147
148 if (!card)
149 return -EINVAL;
150
151 if (card->info.portname_required) {
152 memcpy(portname, card->info.portname + 1, 8);
153 EBCASC(portname, 8);
154 return sprintf(buf, "%s\n", portname);
155 } else
156 return sprintf(buf, "no portname required\n");
157}
158
159static ssize_t qeth_dev_portname_store(struct device *dev,
160 struct device_attribute *attr, const char *buf, size_t count)
161{
162 struct qeth_card *card = dev_get_drvdata(dev);
163 char *tmp;
164 int i;
165
166 if (!card)
167 return -EINVAL;
168
169 if ((card->state != CARD_STATE_DOWN) &&
170 (card->state != CARD_STATE_RECOVER))
171 return -EPERM;
172
173 tmp = strsep((char **) &buf, "\n");
174 if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
175 return -EINVAL;
176
177 card->info.portname[0] = strlen(tmp);
178 /* for beauty reasons */
179 for (i = 1; i < 9; i++)
180 card->info.portname[i] = ' ';
181 strcpy(card->info.portname + 1, tmp);
182 ASCEBC(card->info.portname + 1, 8);
183
184 return count;
185}
186
187static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
188 qeth_dev_portname_store);
189
190static ssize_t qeth_dev_prioqing_show(struct device *dev,
191 struct device_attribute *attr, char *buf)
192{
193 struct qeth_card *card = dev_get_drvdata(dev);
194
195 if (!card)
196 return -EINVAL;
197
198 switch (card->qdio.do_prio_queueing) {
199 case QETH_PRIO_Q_ING_PREC:
200 return sprintf(buf, "%s\n", "by precedence");
201 case QETH_PRIO_Q_ING_TOS:
202 return sprintf(buf, "%s\n", "by type of service");
203 default:
204 return sprintf(buf, "always queue %i\n",
205 card->qdio.default_out_queue);
206 }
207}
208
209static ssize_t qeth_dev_prioqing_store(struct device *dev,
210 struct device_attribute *attr, const char *buf, size_t count)
211{
212 struct qeth_card *card = dev_get_drvdata(dev);
213 char *tmp;
214
215 if (!card)
216 return -EINVAL;
217
218 if ((card->state != CARD_STATE_DOWN) &&
219 (card->state != CARD_STATE_RECOVER))
220 return -EPERM;
221
222 /* check if 1920 devices are supported ,
223 * if though we have to permit priority queueing
224 */
225 if (card->qdio.no_out_queues == 1) {
226 PRINT_WARN("Priority queueing disabled due "
227 "to hardware limitations!\n");
228 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
229 return -EPERM;
230 }
231
232 tmp = strsep((char **) &buf, "\n");
233 if (!strcmp(tmp, "prio_queueing_prec"))
234 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
235 else if (!strcmp(tmp, "prio_queueing_tos"))
236 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
237 else if (!strcmp(tmp, "no_prio_queueing:0")) {
238 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
239 card->qdio.default_out_queue = 0;
240 } else if (!strcmp(tmp, "no_prio_queueing:1")) {
241 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
242 card->qdio.default_out_queue = 1;
243 } else if (!strcmp(tmp, "no_prio_queueing:2")) {
244 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
245 card->qdio.default_out_queue = 2;
246 } else if (!strcmp(tmp, "no_prio_queueing:3")) {
247 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
248 card->qdio.default_out_queue = 3;
249 } else if (!strcmp(tmp, "no_prio_queueing")) {
250 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
251 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
252 } else {
253 PRINT_WARN("Unknown queueing type '%s'\n", tmp);
254 return -EINVAL;
255 }
256 return count;
257}
258
259static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
260 qeth_dev_prioqing_store);
261
262static ssize_t qeth_dev_bufcnt_show(struct device *dev,
263 struct device_attribute *attr, char *buf)
264{
265 struct qeth_card *card = dev_get_drvdata(dev);
266
267 if (!card)
268 return -EINVAL;
269
270 return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);
271}
272
273static ssize_t qeth_dev_bufcnt_store(struct device *dev,
274 struct device_attribute *attr, const char *buf, size_t count)
275{
276 struct qeth_card *card = dev_get_drvdata(dev);
277 char *tmp;
278 int cnt, old_cnt;
279 int rc;
280
281 if (!card)
282 return -EINVAL;
283
284 if ((card->state != CARD_STATE_DOWN) &&
285 (card->state != CARD_STATE_RECOVER))
286 return -EPERM;
287
288 old_cnt = card->qdio.in_buf_pool.buf_count;
289 cnt = simple_strtoul(buf, &tmp, 10);
290 cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
291 ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
292 if (old_cnt != cnt) {
293 rc = qeth_realloc_buffer_pool(card, cnt);
294 if (rc)
295 PRINT_WARN("Error (%d) while setting "
296 "buffer count.\n", rc);
297 }
298 return count;
299}
300
301static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
302 qeth_dev_bufcnt_store);
303
304static ssize_t qeth_dev_recover_store(struct device *dev,
305 struct device_attribute *attr, const char *buf, size_t count)
306{
307 struct qeth_card *card = dev_get_drvdata(dev);
308 char *tmp;
309 int i;
310
311 if (!card)
312 return -EINVAL;
313
314 if (card->state != CARD_STATE_UP)
315 return -EPERM;
316
317 i = simple_strtoul(buf, &tmp, 16);
318 if (i == 1)
319 qeth_schedule_recovery(card);
320
321 return count;
322}
323
324static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
325
326static ssize_t qeth_dev_performance_stats_show(struct device *dev,
327 struct device_attribute *attr, char *buf)
328{
329 struct qeth_card *card = dev_get_drvdata(dev);
330
331 if (!card)
332 return -EINVAL;
333
334 return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
335}
336
337static ssize_t qeth_dev_performance_stats_store(struct device *dev,
338 struct device_attribute *attr, const char *buf, size_t count)
339{
340 struct qeth_card *card = dev_get_drvdata(dev);
341 char *tmp;
342 int i;
343
344 if (!card)
345 return -EINVAL;
346
347 i = simple_strtoul(buf, &tmp, 16);
348 if ((i == 0) || (i == 1)) {
349 if (i == card->options.performance_stats)
350 return count;
351 card->options.performance_stats = i;
352 if (i == 0)
353 memset(&card->perf_stats, 0,
354 sizeof(struct qeth_perf_stats));
355 card->perf_stats.initial_rx_packets = card->stats.rx_packets;
356 card->perf_stats.initial_tx_packets = card->stats.tx_packets;
357 } else {
358 PRINT_WARN("performance_stats: write 0 or 1 to this file!\n");
359 return -EINVAL;
360 }
361 return count;
362}
363
364static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
365 qeth_dev_performance_stats_store);
366
367static ssize_t qeth_dev_layer2_show(struct device *dev,
368 struct device_attribute *attr, char *buf)
369{
370 struct qeth_card *card = dev_get_drvdata(dev);
371
372 if (!card)
373 return -EINVAL;
374
375 return sprintf(buf, "%i\n", card->options.layer2 ? 1:0);
376}
377
378static ssize_t qeth_dev_layer2_store(struct device *dev,
379 struct device_attribute *attr, const char *buf, size_t count)
380{
381 struct qeth_card *card = dev_get_drvdata(dev);
382 char *tmp;
383 int i, rc;
384 enum qeth_discipline_id newdis;
385
386 if (!card)
387 return -EINVAL;
388
389 if (((card->state != CARD_STATE_DOWN) &&
390 (card->state != CARD_STATE_RECOVER)))
391 return -EPERM;
392
393 i = simple_strtoul(buf, &tmp, 16);
394 switch (i) {
395 case 0:
396 newdis = QETH_DISCIPLINE_LAYER3;
397 break;
398 case 1:
399 newdis = QETH_DISCIPLINE_LAYER2;
400 break;
401 default:
402 PRINT_WARN("layer2: write 0 or 1 to this file!\n");
403 return -EINVAL;
404 }
405
406 if (card->options.layer2 == newdis) {
407 return count;
408 } else {
409 if (card->discipline.ccwgdriver) {
410 card->discipline.ccwgdriver->remove(card->gdev);
411 qeth_core_free_discipline(card);
412 }
413 }
414
415 rc = qeth_core_load_discipline(card, newdis);
416 if (rc)
417 return rc;
418
419 rc = card->discipline.ccwgdriver->probe(card->gdev);
420 if (rc)
421 return rc;
422 return count;
423}
424
425static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
426 qeth_dev_layer2_store);
427
428static ssize_t qeth_dev_large_send_show(struct device *dev,
429 struct device_attribute *attr, char *buf)
430{
431 struct qeth_card *card = dev_get_drvdata(dev);
432
433 if (!card)
434 return -EINVAL;
435
436 switch (card->options.large_send) {
437 case QETH_LARGE_SEND_NO:
438 return sprintf(buf, "%s\n", "no");
439 case QETH_LARGE_SEND_EDDP:
440 return sprintf(buf, "%s\n", "EDDP");
441 case QETH_LARGE_SEND_TSO:
442 return sprintf(buf, "%s\n", "TSO");
443 default:
444 return sprintf(buf, "%s\n", "N/A");
445 }
446}
447
448static ssize_t qeth_dev_large_send_store(struct device *dev,
449 struct device_attribute *attr, const char *buf, size_t count)
450{
451 struct qeth_card *card = dev_get_drvdata(dev);
452 enum qeth_large_send_types type;
453 int rc = 0;
454 char *tmp;
455
456 if (!card)
457 return -EINVAL;
458 tmp = strsep((char **) &buf, "\n");
459 if (!strcmp(tmp, "no")) {
460 type = QETH_LARGE_SEND_NO;
461 } else if (!strcmp(tmp, "EDDP")) {
462 type = QETH_LARGE_SEND_EDDP;
463 } else if (!strcmp(tmp, "TSO")) {
464 type = QETH_LARGE_SEND_TSO;
465 } else {
466 PRINT_WARN("large_send: invalid mode %s!\n", tmp);
467 return -EINVAL;
468 }
469 if (card->options.large_send == type)
470 return count;
471 rc = qeth_set_large_send(card, type);
472 if (rc)
473 return rc;
474 return count;
475}
476
477static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
478 qeth_dev_large_send_store);
479
480static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
481{
482
483 if (!card)
484 return -EINVAL;
485
486 return sprintf(buf, "%i\n", value);
487}
488
489static ssize_t qeth_dev_blkt_store(struct qeth_card *card,
490 const char *buf, size_t count, int *value, int max_value)
491{
492 char *tmp;
493 int i;
494
495 if (!card)
496 return -EINVAL;
497
498 if ((card->state != CARD_STATE_DOWN) &&
499 (card->state != CARD_STATE_RECOVER))
500 return -EPERM;
501
502 i = simple_strtoul(buf, &tmp, 10);
503 if (i <= max_value) {
504 *value = i;
505 } else {
506 PRINT_WARN("blkt total time: write values between"
507 " 0 and %d to this file!\n", max_value);
508 return -EINVAL;
509 }
510 return count;
511}
512
513static ssize_t qeth_dev_blkt_total_show(struct device *dev,
514 struct device_attribute *attr, char *buf)
515{
516 struct qeth_card *card = dev_get_drvdata(dev);
517
518 return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);
519}
520
521static ssize_t qeth_dev_blkt_total_store(struct device *dev,
522 struct device_attribute *attr, const char *buf, size_t count)
523{
524 struct qeth_card *card = dev_get_drvdata(dev);
525
526 return qeth_dev_blkt_store(card, buf, count,
527 &card->info.blkt.time_total, 1000);
528}
529
530
531
532static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
533 qeth_dev_blkt_total_store);
534
535static ssize_t qeth_dev_blkt_inter_show(struct device *dev,
536 struct device_attribute *attr, char *buf)
537{
538 struct qeth_card *card = dev_get_drvdata(dev);
539
540 return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);
541}
542
543static ssize_t qeth_dev_blkt_inter_store(struct device *dev,
544 struct device_attribute *attr, const char *buf, size_t count)
545{
546 struct qeth_card *card = dev_get_drvdata(dev);
547
548 return qeth_dev_blkt_store(card, buf, count,
549 &card->info.blkt.inter_packet, 100);
550}
551
552static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
553 qeth_dev_blkt_inter_store);
554
555static ssize_t qeth_dev_blkt_inter_jumbo_show(struct device *dev,
556 struct device_attribute *attr, char *buf)
557{
558 struct qeth_card *card = dev_get_drvdata(dev);
559
560 return qeth_dev_blkt_show(buf, card,
561 card->info.blkt.inter_packet_jumbo);
562}
563
564static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,
565 struct device_attribute *attr, const char *buf, size_t count)
566{
567 struct qeth_card *card = dev_get_drvdata(dev);
568
569 return qeth_dev_blkt_store(card, buf, count,
570 &card->info.blkt.inter_packet_jumbo, 100);
571}
572
573static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
574 qeth_dev_blkt_inter_jumbo_store);
575
576static struct attribute *qeth_blkt_device_attrs[] = {
577 &dev_attr_total.attr,
578 &dev_attr_inter.attr,
579 &dev_attr_inter_jumbo.attr,
580 NULL,
581};
582
583static struct attribute_group qeth_device_blkt_group = {
584 .name = "blkt",
585 .attrs = qeth_blkt_device_attrs,
586};
587
588static struct attribute *qeth_device_attrs[] = {
589 &dev_attr_state.attr,
590 &dev_attr_chpid.attr,
591 &dev_attr_if_name.attr,
592 &dev_attr_card_type.attr,
593 &dev_attr_inbuf_size.attr,
594 &dev_attr_portno.attr,
595 &dev_attr_portname.attr,
596 &dev_attr_priority_queueing.attr,
597 &dev_attr_buffer_count.attr,
598 &dev_attr_recover.attr,
599 &dev_attr_performance_stats.attr,
600 &dev_attr_layer2.attr,
601 &dev_attr_large_send.attr,
602 NULL,
603};
604
605static struct attribute_group qeth_device_attr_group = {
606 .attrs = qeth_device_attrs,
607};
608
609static struct attribute *qeth_osn_device_attrs[] = {
610 &dev_attr_state.attr,
611 &dev_attr_chpid.attr,
612 &dev_attr_if_name.attr,
613 &dev_attr_card_type.attr,
614 &dev_attr_buffer_count.attr,
615 &dev_attr_recover.attr,
616 NULL,
617};
618
619static struct attribute_group qeth_osn_device_attr_group = {
620 .attrs = qeth_osn_device_attrs,
621};
622
623int qeth_core_create_device_attributes(struct device *dev)
624{
625 int ret;
626 ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group);
627 if (ret)
628 return ret;
629 ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group);
630 if (ret)
631 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
632
633 return 0;
634}
635
636void qeth_core_remove_device_attributes(struct device *dev)
637{
638 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
639 sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group);
640}
641
642int qeth_core_create_osn_attributes(struct device *dev)
643{
644 return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group);
645}
646
647void qeth_core_remove_osn_attributes(struct device *dev)
648{
649 sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
650 return;
651}
diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h
deleted file mode 100644
index 61faf05517d6..000000000000
--- a/drivers/s390/net/qeth_fs.h
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2 * linux/drivers/s390/net/qeth_fs.h
3 *
4 * Linux on zSeries OSA Express and HiperSockets support.
5 *
6 * This header file contains definitions related to sysfs and procfs.
7 *
8 * Copyright 2000,2003 IBM Corporation
9 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
10 *
11 */
12#ifndef __QETH_FS_H__
13#define __QETH_FS_H__
14
15#ifdef CONFIG_PROC_FS
16extern int
17qeth_create_procfs_entries(void);
18
19extern void
20qeth_remove_procfs_entries(void);
21#else
22static inline int
23qeth_create_procfs_entries(void)
24{
25 return 0;
26}
27
28static inline void
29qeth_remove_procfs_entries(void)
30{
31}
32#endif /* CONFIG_PROC_FS */
33
34extern int
35qeth_create_device_attributes(struct device *dev);
36
37extern void
38qeth_remove_device_attributes(struct device *dev);
39
40extern int
41qeth_create_device_attributes_osn(struct device *dev);
42
43extern void
44qeth_remove_device_attributes_osn(struct device *dev);
45
46extern int
47qeth_create_driver_attributes(void);
48
49extern void
50qeth_remove_driver_attributes(void);
51
52/*
53 * utility functions used in qeth_proc.c and qeth_sys.c
54 */
55
56static inline const char *
57qeth_get_checksum_str(struct qeth_card *card)
58{
59 if (card->options.checksum_type == SW_CHECKSUMMING)
60 return "sw";
61 else if (card->options.checksum_type == HW_CHECKSUMMING)
62 return "hw";
63 else
64 return "no";
65}
66
67static inline const char *
68qeth_get_prioq_str(struct qeth_card *card, char *buf)
69{
70 if (card->qdio.do_prio_queueing == QETH_NO_PRIO_QUEUEING)
71 sprintf(buf, "always_q_%i", card->qdio.default_out_queue);
72 else
73 strcpy(buf, (card->qdio.do_prio_queueing ==
74 QETH_PRIO_Q_ING_PREC)?
75 "by_prec." : "by_ToS");
76 return buf;
77}
78
79static inline const char *
80qeth_get_bufsize_str(struct qeth_card *card)
81{
82 if (card->qdio.in_buf_size == 16384)
83 return "16k";
84 else if (card->qdio.in_buf_size == 24576)
85 return "24k";
86 else if (card->qdio.in_buf_size == 32768)
87 return "32k";
88 else if (card->qdio.in_buf_size == 40960)
89 return "40k";
90 else
91 return "64k";
92}
93
94static inline const char *
95qeth_get_cardname(struct qeth_card *card)
96{
97 if (card->info.guestlan) {
98 switch (card->info.type) {
99 case QETH_CARD_TYPE_OSAE:
100 return " Guest LAN QDIO";
101 case QETH_CARD_TYPE_IQD:
102 return " Guest LAN Hiper";
103 default:
104 return " unknown";
105 }
106 } else {
107 switch (card->info.type) {
108 case QETH_CARD_TYPE_OSAE:
109 return " OSD Express";
110 case QETH_CARD_TYPE_IQD:
111 return " HiperSockets";
112 case QETH_CARD_TYPE_OSN:
113 return " OSN QDIO";
114 default:
115 return " unknown";
116 }
117 }
118 return " n/a";
119}
120
121/* max length to be returned: 14 */
122static inline const char *
123qeth_get_cardname_short(struct qeth_card *card)
124{
125 if (card->info.guestlan){
126 switch (card->info.type){
127 case QETH_CARD_TYPE_OSAE:
128 return "GuestLAN QDIO";
129 case QETH_CARD_TYPE_IQD:
130 return "GuestLAN Hiper";
131 default:
132 return "unknown";
133 }
134 } else {
135 switch (card->info.type) {
136 case QETH_CARD_TYPE_OSAE:
137 switch (card->info.link_type) {
138 case QETH_LINK_TYPE_FAST_ETH:
139 return "OSD_100";
140 case QETH_LINK_TYPE_HSTR:
141 return "HSTR";
142 case QETH_LINK_TYPE_GBIT_ETH:
143 return "OSD_1000";
144 case QETH_LINK_TYPE_10GBIT_ETH:
145 return "OSD_10GIG";
146 case QETH_LINK_TYPE_LANE_ETH100:
147 return "OSD_FE_LANE";
148 case QETH_LINK_TYPE_LANE_TR:
149 return "OSD_TR_LANE";
150 case QETH_LINK_TYPE_LANE_ETH1000:
151 return "OSD_GbE_LANE";
152 case QETH_LINK_TYPE_LANE:
153 return "OSD_ATM_LANE";
154 default:
155 return "OSD_Express";
156 }
157 case QETH_CARD_TYPE_IQD:
158 return "HiperSockets";
159 case QETH_CARD_TYPE_OSN:
160 return "OSN";
161 default:
162 return "unknown";
163 }
164 }
165 return "n/a";
166}
167
168#endif /* __QETH_FS_H__ */
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
new file mode 100644
index 000000000000..4417a3629ae0
--- /dev/null
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -0,0 +1,1242 @@
1/*
2 * drivers/s390/net/qeth_l2_main.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/string.h>
14#include <linux/errno.h>
15#include <linux/kernel.h>
16#include <linux/etherdevice.h>
17#include <linux/mii.h>
18#include <linux/ip.h>
19
20#include <asm/s390_rdev.h>
21
22#include "qeth_core.h"
23#include "qeth_core_offl.h"
24
25#define QETH_DBF_TEXT_(name, level, text...) \
26 do { \
27 if (qeth_dbf_passes(qeth_dbf_##name, level)) { \
28 char *dbf_txt_buf = get_cpu_var(qeth_l2_dbf_txt_buf); \
29 sprintf(dbf_txt_buf, text); \
30 debug_text_event(qeth_dbf_##name, level, dbf_txt_buf); \
31 put_cpu_var(qeth_l2_dbf_txt_buf); \
32 } \
33 } while (0)
34
35static DEFINE_PER_CPU(char[256], qeth_l2_dbf_txt_buf);
36
37static int qeth_l2_set_offline(struct ccwgroup_device *);
38static int qeth_l2_stop(struct net_device *);
39static int qeth_l2_send_delmac(struct qeth_card *, __u8 *);
40static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *,
41 enum qeth_ipa_cmds,
42 int (*reply_cb) (struct qeth_card *,
43 struct qeth_reply*,
44 unsigned long));
45static void qeth_l2_set_multicast_list(struct net_device *);
46static int qeth_l2_recover(void *);
47
48static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
49{
50 struct qeth_card *card = netdev_priv(dev);
51 struct mii_ioctl_data *mii_data;
52 int rc = 0;
53
54 if (!card)
55 return -ENODEV;
56
57 if ((card->state != CARD_STATE_UP) &&
58 (card->state != CARD_STATE_SOFTSETUP))
59 return -ENODEV;
60
61 if (card->info.type == QETH_CARD_TYPE_OSN)
62 return -EPERM;
63
64 switch (cmd) {
65 case SIOC_QETH_ADP_SET_SNMP_CONTROL:
66 rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
67 break;
68 case SIOC_QETH_GET_CARD_TYPE:
69 if ((card->info.type == QETH_CARD_TYPE_OSAE) &&
70 !card->info.guestlan)
71 return 1;
72 return 0;
73 break;
74 case SIOCGMIIPHY:
75 mii_data = if_mii(rq);
76 mii_data->phy_id = 0;
77 break;
78 case SIOCGMIIREG:
79 mii_data = if_mii(rq);
80 if (mii_data->phy_id != 0)
81 rc = -EINVAL;
82 else
83 mii_data->val_out = qeth_mdio_read(dev,
84 mii_data->phy_id, mii_data->reg_num);
85 break;
86 default:
87 rc = -EOPNOTSUPP;
88 }
89 if (rc)
90 QETH_DBF_TEXT_(trace, 2, "ioce%d", rc);
91 return rc;
92}
93
94static int qeth_l2_verify_dev(struct net_device *dev)
95{
96 struct qeth_card *card;
97 unsigned long flags;
98 int rc = 0;
99
100 read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
101 list_for_each_entry(card, &qeth_core_card_list.list, list) {
102 if (card->dev == dev) {
103 rc = QETH_REAL_CARD;
104 break;
105 }
106 }
107 read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
108
109 return rc;
110}
111
112static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no)
113{
114 struct qeth_card *card;
115 struct net_device *ndev;
116 unsigned char *readno;
117 __u16 temp_dev_no, card_dev_no;
118 char *endp;
119 unsigned long flags;
120
121 ndev = NULL;
122 memcpy(&temp_dev_no, read_dev_no, 2);
123 read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
124 list_for_each_entry(card, &qeth_core_card_list.list, list) {
125 readno = CARD_RDEV_ID(card);
126 readno += (strlen(readno) - 4);
127 card_dev_no = simple_strtoul(readno, &endp, 16);
128 if (card_dev_no == temp_dev_no) {
129 ndev = card->dev;
130 break;
131 }
132 }
133 read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
134 return ndev;
135}
136
137static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card,
138 struct qeth_reply *reply,
139 unsigned long data)
140{
141 struct qeth_ipa_cmd *cmd;
142 __u8 *mac;
143
144 QETH_DBF_TEXT(trace, 2, "L2Sgmacb");
145 cmd = (struct qeth_ipa_cmd *) data;
146 mac = &cmd->data.setdelmac.mac[0];
147 /* MAC already registered, needed in couple/uncouple case */
148 if (cmd->hdr.return_code == 0x2005) {
149 PRINT_WARN("Group MAC %02x:%02x:%02x:%02x:%02x:%02x " \
150 "already existing on %s \n",
151 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
152 QETH_CARD_IFNAME(card));
153 cmd->hdr.return_code = 0;
154 }
155 if (cmd->hdr.return_code)
156 PRINT_ERR("Could not set group MAC " \
157 "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
158 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
159 QETH_CARD_IFNAME(card), cmd->hdr.return_code);
160 return 0;
161}
162
163static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
164{
165 QETH_DBF_TEXT(trace, 2, "L2Sgmac");
166 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC,
167 qeth_l2_send_setgroupmac_cb);
168}
169
170static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card,
171 struct qeth_reply *reply,
172 unsigned long data)
173{
174 struct qeth_ipa_cmd *cmd;
175 __u8 *mac;
176
177 QETH_DBF_TEXT(trace, 2, "L2Dgmacb");
178 cmd = (struct qeth_ipa_cmd *) data;
179 mac = &cmd->data.setdelmac.mac[0];
180 if (cmd->hdr.return_code)
181 PRINT_ERR("Could not delete group MAC " \
182 "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
183 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
184 QETH_CARD_IFNAME(card), cmd->hdr.return_code);
185 return 0;
186}
187
188static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
189{
190 QETH_DBF_TEXT(trace, 2, "L2Dgmac");
191 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC,
192 qeth_l2_send_delgroupmac_cb);
193}
194
195static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac)
196{
197 struct qeth_mc_mac *mc;
198
199 mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC);
200
201 if (!mc) {
202 PRINT_ERR("no mem vor mc mac address\n");
203 return;
204 }
205
206 memcpy(mc->mc_addr, mac, OSA_ADDR_LEN);
207 mc->mc_addrlen = OSA_ADDR_LEN;
208
209 if (!qeth_l2_send_setgroupmac(card, mac))
210 list_add_tail(&mc->list, &card->mc_list);
211 else
212 kfree(mc);
213}
214
215static void qeth_l2_del_all_mc(struct qeth_card *card)
216{
217 struct qeth_mc_mac *mc, *tmp;
218
219 spin_lock_bh(&card->mclock);
220 list_for_each_entry_safe(mc, tmp, &card->mc_list, list) {
221 qeth_l2_send_delgroupmac(card, mc->mc_addr);
222 list_del(&mc->list);
223 kfree(mc);
224 }
225 spin_unlock_bh(&card->mclock);
226}
227
228static void qeth_l2_get_packet_type(struct qeth_card *card,
229 struct qeth_hdr *hdr, struct sk_buff *skb)
230{
231 __u16 hdr_mac;
232
233 if (!memcmp(skb->data + QETH_HEADER_SIZE,
234 skb->dev->broadcast, 6)) {
235 /* broadcast? */
236 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_BROADCAST;
237 return;
238 }
239 hdr_mac = *((__u16 *)skb->data);
240 /* tr multicast? */
241 switch (card->info.link_type) {
242 case QETH_LINK_TYPE_HSTR:
243 case QETH_LINK_TYPE_LANE_TR:
244 if ((hdr_mac == QETH_TR_MAC_NC) ||
245 (hdr_mac == QETH_TR_MAC_C))
246 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
247 else
248 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST;
249 break;
250 /* eth or so multicast? */
251 default:
252 if ((hdr_mac == QETH_ETH_MAC_V4) ||
253 (hdr_mac == QETH_ETH_MAC_V6))
254 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
255 else
256 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST;
257 }
258}
259
260static void qeth_l2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
261 struct sk_buff *skb, int ipv, int cast_type)
262{
263 struct vlan_ethhdr *veth = (struct vlan_ethhdr *)((skb->data) +
264 QETH_HEADER_SIZE);
265
266 memset(hdr, 0, sizeof(struct qeth_hdr));
267 hdr->hdr.l2.id = QETH_HEADER_TYPE_LAYER2;
268
269 /* set byte byte 3 to casting flags */
270 if (cast_type == RTN_MULTICAST)
271 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
272 else if (cast_type == RTN_BROADCAST)
273 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_BROADCAST;
274 else
275 qeth_l2_get_packet_type(card, hdr, skb);
276
277 hdr->hdr.l2.pkt_length = skb->len-QETH_HEADER_SIZE;
278 /* VSWITCH relies on the VLAN
279 * information to be present in
280 * the QDIO header */
281 if (veth->h_vlan_proto == __constant_htons(ETH_P_8021Q)) {
282 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_VLAN;
283 hdr->hdr.l2.vlan_id = ntohs(veth->h_vlan_TCI);
284 }
285}
286
287static int qeth_l2_send_setdelvlan_cb(struct qeth_card *card,
288 struct qeth_reply *reply, unsigned long data)
289{
290 struct qeth_ipa_cmd *cmd;
291
292 QETH_DBF_TEXT(trace, 2, "L2sdvcb");
293 cmd = (struct qeth_ipa_cmd *) data;
294 if (cmd->hdr.return_code) {
295 PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
296 "Continuing\n", cmd->data.setdelvlan.vlan_id,
297 QETH_CARD_IFNAME(card), cmd->hdr.return_code);
298 QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
299 QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
300 QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
301 }
302 return 0;
303}
304
305static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i,
306 enum qeth_ipa_cmds ipacmd)
307{
308 struct qeth_ipa_cmd *cmd;
309 struct qeth_cmd_buffer *iob;
310
311 QETH_DBF_TEXT_(trace, 4, "L2sdv%x", ipacmd);
312 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
313 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
314 cmd->data.setdelvlan.vlan_id = i;
315 return qeth_send_ipa_cmd(card, iob,
316 qeth_l2_send_setdelvlan_cb, NULL);
317}
318
319static void qeth_l2_process_vlans(struct qeth_card *card, int clear)
320{
321 struct qeth_vlan_vid *id;
322 QETH_DBF_TEXT(trace, 3, "L2prcvln");
323 spin_lock_bh(&card->vlanlock);
324 list_for_each_entry(id, &card->vid_list, list) {
325 if (clear)
326 qeth_l2_send_setdelvlan(card, id->vid,
327 IPA_CMD_DELVLAN);
328 else
329 qeth_l2_send_setdelvlan(card, id->vid,
330 IPA_CMD_SETVLAN);
331 }
332 spin_unlock_bh(&card->vlanlock);
333}
334
335static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
336{
337 struct qeth_card *card = netdev_priv(dev);
338 struct qeth_vlan_vid *id;
339
340 QETH_DBF_TEXT_(trace, 4, "aid:%d", vid);
341 id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC);
342 if (id) {
343 id->vid = vid;
344 qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN);
345 spin_lock_bh(&card->vlanlock);
346 list_add_tail(&id->list, &card->vid_list);
347 spin_unlock_bh(&card->vlanlock);
348 } else {
349 PRINT_ERR("no memory for vid\n");
350 }
351}
352
353static void qeth_l2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
354{
355 struct qeth_vlan_vid *id, *tmpid = NULL;
356 struct qeth_card *card = netdev_priv(dev);
357
358 QETH_DBF_TEXT_(trace, 4, "kid:%d", vid);
359 spin_lock_bh(&card->vlanlock);
360 list_for_each_entry(id, &card->vid_list, list) {
361 if (id->vid == vid) {
362 list_del(&id->list);
363 tmpid = id;
364 break;
365 }
366 }
367 spin_unlock_bh(&card->vlanlock);
368 if (tmpid) {
369 qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
370 kfree(tmpid);
371 }
372 qeth_l2_set_multicast_list(card->dev);
373}
374
375static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
376{
377 int rc = 0;
378
379 QETH_DBF_TEXT(setup , 2, "stopcard");
380 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
381
382 qeth_set_allowed_threads(card, 0, 1);
383 if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD))
384 return -ERESTARTSYS;
385 if (card->read.state == CH_STATE_UP &&
386 card->write.state == CH_STATE_UP &&
387 (card->state == CARD_STATE_UP)) {
388 if (recovery_mode &&
389 card->info.type != QETH_CARD_TYPE_OSN) {
390 qeth_l2_stop(card->dev);
391 } else {
392 rtnl_lock();
393 dev_close(card->dev);
394 rtnl_unlock();
395 }
396 if (!card->use_hard_stop) {
397 __u8 *mac = &card->dev->dev_addr[0];
398 rc = qeth_l2_send_delmac(card, mac);
399 QETH_DBF_TEXT_(setup, 2, "Lerr%d", rc);
400 }
401 card->state = CARD_STATE_SOFTSETUP;
402 }
403 if (card->state == CARD_STATE_SOFTSETUP) {
404 qeth_l2_process_vlans(card, 1);
405 qeth_l2_del_all_mc(card);
406 qeth_clear_ipacmd_list(card);
407 card->state = CARD_STATE_HARDSETUP;
408 }
409 if (card->state == CARD_STATE_HARDSETUP) {
410 qeth_qdio_clear_card(card, 0);
411 qeth_clear_qdio_buffers(card);
412 qeth_clear_working_pool_list(card);
413 card->state = CARD_STATE_DOWN;
414 }
415 if (card->state == CARD_STATE_DOWN) {
416 qeth_clear_cmd_buffers(&card->read);
417 qeth_clear_cmd_buffers(&card->write);
418 }
419 card->use_hard_stop = 0;
420 return rc;
421}
422
423static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
424 struct qeth_qdio_buffer *buf, int index)
425{
426 struct qdio_buffer_element *element;
427 struct sk_buff *skb;
428 struct qeth_hdr *hdr;
429 int offset;
430 unsigned int len;
431
432 /* get first element of current buffer */
433 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
434 offset = 0;
435 if (card->options.performance_stats)
436 card->perf_stats.bufs_rec++;
437 while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
438 &offset, &hdr))) {
439 skb->dev = card->dev;
440 /* is device UP ? */
441 if (!(card->dev->flags & IFF_UP)) {
442 dev_kfree_skb_any(skb);
443 continue;
444 }
445
446 switch (hdr->hdr.l2.id) {
447 case QETH_HEADER_TYPE_LAYER2:
448 skb->pkt_type = PACKET_HOST;
449 skb->protocol = eth_type_trans(skb, skb->dev);
450 if (card->options.checksum_type == NO_CHECKSUMMING)
451 skb->ip_summed = CHECKSUM_UNNECESSARY;
452 else
453 skb->ip_summed = CHECKSUM_NONE;
454 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
455 len = skb->len;
456 netif_rx(skb);
457 break;
458 case QETH_HEADER_TYPE_OSN:
459 skb_push(skb, sizeof(struct qeth_hdr));
460 skb_copy_to_linear_data(skb, hdr,
461 sizeof(struct qeth_hdr));
462 len = skb->len;
463 card->osn_info.data_cb(skb);
464 break;
465 default:
466 dev_kfree_skb_any(skb);
467 QETH_DBF_TEXT(trace, 3, "inbunkno");
468 QETH_DBF_HEX(control, 3, hdr, QETH_DBF_CONTROL_LEN);
469 continue;
470 }
471 card->dev->last_rx = jiffies;
472 card->stats.rx_packets++;
473 card->stats.rx_bytes += len;
474 }
475}
476
477static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
478 enum qeth_ipa_cmds ipacmd,
479 int (*reply_cb) (struct qeth_card *,
480 struct qeth_reply*,
481 unsigned long))
482{
483 struct qeth_ipa_cmd *cmd;
484 struct qeth_cmd_buffer *iob;
485
486 QETH_DBF_TEXT(trace, 2, "L2sdmac");
487 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
488 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
489 cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
490 memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
491 return qeth_send_ipa_cmd(card, iob, reply_cb, NULL);
492}
493
494static int qeth_l2_send_setmac_cb(struct qeth_card *card,
495 struct qeth_reply *reply,
496 unsigned long data)
497{
498 struct qeth_ipa_cmd *cmd;
499
500 QETH_DBF_TEXT(trace, 2, "L2Smaccb");
501 cmd = (struct qeth_ipa_cmd *) data;
502 if (cmd->hdr.return_code) {
503 QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code);
504 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
505 cmd->hdr.return_code = -EIO;
506 } else {
507 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
508 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac,
509 OSA_ADDR_LEN);
510 PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
511 "successfully registered on device %s\n",
512 card->dev->dev_addr[0], card->dev->dev_addr[1],
513 card->dev->dev_addr[2], card->dev->dev_addr[3],
514 card->dev->dev_addr[4], card->dev->dev_addr[5],
515 card->dev->name);
516 }
517 return 0;
518}
519
520static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
521{
522 QETH_DBF_TEXT(trace, 2, "L2Setmac");
523 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
524 qeth_l2_send_setmac_cb);
525}
526
527static int qeth_l2_send_delmac_cb(struct qeth_card *card,
528 struct qeth_reply *reply,
529 unsigned long data)
530{
531 struct qeth_ipa_cmd *cmd;
532
533 QETH_DBF_TEXT(trace, 2, "L2Dmaccb");
534 cmd = (struct qeth_ipa_cmd *) data;
535 if (cmd->hdr.return_code) {
536 QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
537 cmd->hdr.return_code = -EIO;
538 return 0;
539 }
540 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
541
542 return 0;
543}
544
545static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
546{
547 QETH_DBF_TEXT(trace, 2, "L2Delmac");
548 if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
549 return 0;
550 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
551 qeth_l2_send_delmac_cb);
552}
553
554static int qeth_l2_request_initial_mac(struct qeth_card *card)
555{
556 int rc = 0;
557 char vendor_pre[] = {0x02, 0x00, 0x00};
558
559 QETH_DBF_TEXT(setup, 2, "doL2init");
560 QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));
561
562 rc = qeth_query_setadapterparms(card);
563 if (rc) {
564 PRINT_WARN("could not query adapter parameters on device %s: "
565 "x%x\n", CARD_BUS_ID(card), rc);
566 }
567
568 if (card->info.guestlan) {
569 rc = qeth_setadpparms_change_macaddr(card);
570 if (rc) {
571 PRINT_WARN("couldn't get MAC address on "
572 "device %s: x%x\n",
573 CARD_BUS_ID(card), rc);
574 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
575 return rc;
576 }
577 QETH_DBF_HEX(setup, 2, card->dev->dev_addr, OSA_ADDR_LEN);
578 } else {
579 random_ether_addr(card->dev->dev_addr);
580 memcpy(card->dev->dev_addr, vendor_pre, 3);
581 }
582 return 0;
583}
584
585static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
586{
587 struct sockaddr *addr = p;
588 struct qeth_card *card = netdev_priv(dev);
589 int rc = 0;
590
591 QETH_DBF_TEXT(trace, 3, "setmac");
592
593 if (qeth_l2_verify_dev(dev) != QETH_REAL_CARD) {
594 QETH_DBF_TEXT(trace, 3, "setmcINV");
595 return -EOPNOTSUPP;
596 }
597
598 if (card->info.type == QETH_CARD_TYPE_OSN) {
599 PRINT_WARN("Setting MAC address on %s is not supported.\n",
600 dev->name);
601 QETH_DBF_TEXT(trace, 3, "setmcOSN");
602 return -EOPNOTSUPP;
603 }
604 QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
605 QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
606 rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
607 if (!rc)
608 rc = qeth_l2_send_setmac(card, addr->sa_data);
609 return rc;
610}
611
612static void qeth_l2_set_multicast_list(struct net_device *dev)
613{
614 struct qeth_card *card = netdev_priv(dev);
615 struct dev_mc_list *dm;
616
617 if (card->info.type == QETH_CARD_TYPE_OSN)
618 return ;
619
620 QETH_DBF_TEXT(trace, 3, "setmulti");
621 qeth_l2_del_all_mc(card);
622 spin_lock_bh(&card->mclock);
623 for (dm = dev->mc_list; dm; dm = dm->next)
624 qeth_l2_add_mc(card, dm->dmi_addr);
625 spin_unlock_bh(&card->mclock);
626 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
627 return;
628 qeth_setadp_promisc_mode(card);
629}
630
631static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
632{
633 int rc;
634 struct qeth_hdr *hdr = NULL;
635 int elements = 0;
636 struct qeth_card *card = netdev_priv(dev);
637 struct sk_buff *new_skb = skb;
638 int ipv = qeth_get_ip_version(skb);
639 int cast_type = qeth_get_cast_type(card, skb);
640 struct qeth_qdio_out_q *queue = card->qdio.out_qs
641 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
642 int tx_bytes = skb->len;
643 enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
644 struct qeth_eddp_context *ctx = NULL;
645
646 QETH_DBF_TEXT(trace, 6, "l2xmit");
647
648 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
649 card->stats.tx_carrier_errors++;
650 goto tx_drop;
651 }
652
653 if ((card->info.type == QETH_CARD_TYPE_OSN) &&
654 (skb->protocol == htons(ETH_P_IPV6)))
655 goto tx_drop;
656
657 if (card->options.performance_stats) {
658 card->perf_stats.outbound_cnt++;
659 card->perf_stats.outbound_start_time = qeth_get_micros();
660 }
661 netif_stop_queue(dev);
662
663 if (skb_is_gso(skb))
664 large_send = QETH_LARGE_SEND_EDDP;
665
666 if (card->info.type == QETH_CARD_TYPE_OSN)
667 hdr = (struct qeth_hdr *)skb->data;
668 else {
669 new_skb = qeth_prepare_skb(card, skb, &hdr);
670 if (!new_skb)
671 goto tx_drop;
672 qeth_l2_fill_header(card, hdr, new_skb, ipv, cast_type);
673 }
674
675 if (large_send == QETH_LARGE_SEND_EDDP) {
676 ctx = qeth_eddp_create_context(card, new_skb, hdr,
677 skb->sk->sk_protocol);
678 if (ctx == NULL) {
679 PRINT_WARN("could not create eddp context\n");
680 goto tx_drop;
681 }
682 } else {
683 elements = qeth_get_elements_no(card, (void *)hdr, new_skb, 0);
684 if (!elements)
685 goto tx_drop;
686 }
687
688 if ((large_send == QETH_LARGE_SEND_NO) &&
689 (skb->ip_summed == CHECKSUM_PARTIAL))
690 qeth_tx_csum(new_skb);
691
692 if (card->info.type != QETH_CARD_TYPE_IQD)
693 rc = qeth_do_send_packet(card, queue, new_skb, hdr,
694 elements, ctx);
695 else
696 rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
697 elements, ctx);
698 if (!rc) {
699 card->stats.tx_packets++;
700 card->stats.tx_bytes += tx_bytes;
701 if (new_skb != skb)
702 dev_kfree_skb_any(skb);
703 if (card->options.performance_stats) {
704 if (large_send != QETH_LARGE_SEND_NO) {
705 card->perf_stats.large_send_bytes += tx_bytes;
706 card->perf_stats.large_send_cnt++;
707 }
708 if (skb_shinfo(new_skb)->nr_frags > 0) {
709 card->perf_stats.sg_skbs_sent++;
710 /* nr_frags + skb->data */
711 card->perf_stats.sg_frags_sent +=
712 skb_shinfo(new_skb)->nr_frags + 1;
713 }
714 }
715
716 if (ctx != NULL) {
717 qeth_eddp_put_context(ctx);
718 dev_kfree_skb_any(new_skb);
719 }
720 } else {
721 if (ctx != NULL)
722 qeth_eddp_put_context(ctx);
723
724 if (rc == -EBUSY) {
725 if (new_skb != skb)
726 dev_kfree_skb_any(new_skb);
727 return NETDEV_TX_BUSY;
728 } else
729 goto tx_drop;
730 }
731
732 netif_wake_queue(dev);
733 if (card->options.performance_stats)
734 card->perf_stats.outbound_time += qeth_get_micros() -
735 card->perf_stats.outbound_start_time;
736 return rc;
737
738tx_drop:
739 card->stats.tx_dropped++;
740 card->stats.tx_errors++;
741 if ((new_skb != skb) && new_skb)
742 dev_kfree_skb_any(new_skb);
743 dev_kfree_skb_any(skb);
744 return NETDEV_TX_OK;
745}
746
747static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
748 unsigned int status, unsigned int qdio_err,
749 unsigned int siga_err, unsigned int queue,
750 int first_element, int count, unsigned long card_ptr)
751{
752 struct net_device *net_dev;
753 struct qeth_card *card;
754 struct qeth_qdio_buffer *buffer;
755 int index;
756 int i;
757
758 QETH_DBF_TEXT(trace, 6, "qdinput");
759 card = (struct qeth_card *) card_ptr;
760 net_dev = card->dev;
761 if (card->options.performance_stats) {
762 card->perf_stats.inbound_cnt++;
763 card->perf_stats.inbound_start_time = qeth_get_micros();
764 }
765 if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
766 if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
767 QETH_DBF_TEXT(trace, 1, "qdinchk");
768 QETH_DBF_TEXT_(trace, 1, "%s", CARD_BUS_ID(card));
769 QETH_DBF_TEXT_(trace, 1, "%04X%04X", first_element,
770 count);
771 QETH_DBF_TEXT_(trace, 1, "%04X%04X", queue, status);
772 qeth_schedule_recovery(card);
773 return;
774 }
775 }
776 for (i = first_element; i < (first_element + count); ++i) {
777 index = i % QDIO_MAX_BUFFERS_PER_Q;
778 buffer = &card->qdio.in_q->bufs[index];
779 if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
780 qeth_check_qdio_errors(buffer->buffer,
781 qdio_err, siga_err, "qinerr")))
782 qeth_l2_process_inbound_buffer(card, buffer, index);
783 /* clear buffer and give back to hardware */
784 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
785 qeth_queue_input_buffer(card, index);
786 }
787 if (card->options.performance_stats)
788 card->perf_stats.inbound_time += qeth_get_micros() -
789 card->perf_stats.inbound_start_time;
790}
791
792static int qeth_l2_open(struct net_device *dev)
793{
794 struct qeth_card *card = netdev_priv(dev);
795
796 QETH_DBF_TEXT(trace, 4, "qethopen");
797 if (card->state != CARD_STATE_SOFTSETUP)
798 return -ENODEV;
799
800 if ((card->info.type != QETH_CARD_TYPE_OSN) &&
801 (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
802 QETH_DBF_TEXT(trace, 4, "nomacadr");
803 return -EPERM;
804 }
805 card->data.state = CH_STATE_UP;
806 card->state = CARD_STATE_UP;
807 card->dev->flags |= IFF_UP;
808 netif_start_queue(dev);
809
810 if (!card->lan_online && netif_carrier_ok(dev))
811 netif_carrier_off(dev);
812 return 0;
813}
814
815
816static int qeth_l2_stop(struct net_device *dev)
817{
818 struct qeth_card *card = netdev_priv(dev);
819
820 QETH_DBF_TEXT(trace, 4, "qethstop");
821 netif_tx_disable(dev);
822 card->dev->flags &= ~IFF_UP;
823 if (card->state == CARD_STATE_UP)
824 card->state = CARD_STATE_SOFTSETUP;
825 return 0;
826}
827
828static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
829{
830 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
831
832 INIT_LIST_HEAD(&card->vid_list);
833 INIT_LIST_HEAD(&card->mc_list);
834 card->options.layer2 = 1;
835 card->discipline.input_handler = (qdio_handler_t *)
836 qeth_l2_qdio_input_handler;
837 card->discipline.output_handler = (qdio_handler_t *)
838 qeth_qdio_output_handler;
839 card->discipline.recover = qeth_l2_recover;
840 return 0;
841}
842
843static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
844{
845 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
846
847 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
848
849 if (cgdev->state == CCWGROUP_ONLINE) {
850 card->use_hard_stop = 1;
851 qeth_l2_set_offline(cgdev);
852 }
853
854 if (card->dev) {
855 unregister_netdev(card->dev);
856 card->dev = NULL;
857 }
858
859 qeth_l2_del_all_mc(card);
860 return;
861}
862
863static struct ethtool_ops qeth_l2_ethtool_ops = {
864 .get_link = ethtool_op_get_link,
865 .get_tx_csum = ethtool_op_get_tx_csum,
866 .set_tx_csum = ethtool_op_set_tx_hw_csum,
867 .get_sg = ethtool_op_get_sg,
868 .set_sg = ethtool_op_set_sg,
869 .get_tso = ethtool_op_get_tso,
870 .set_tso = ethtool_op_set_tso,
871 .get_strings = qeth_core_get_strings,
872 .get_ethtool_stats = qeth_core_get_ethtool_stats,
873 .get_stats_count = qeth_core_get_stats_count,
874 .get_drvinfo = qeth_core_get_drvinfo,
875};
876
877static struct ethtool_ops qeth_l2_osn_ops = {
878 .get_strings = qeth_core_get_strings,
879 .get_ethtool_stats = qeth_core_get_ethtool_stats,
880 .get_stats_count = qeth_core_get_stats_count,
881 .get_drvinfo = qeth_core_get_drvinfo,
882};
883
884static int qeth_l2_setup_netdev(struct qeth_card *card)
885{
886 switch (card->info.type) {
887 case QETH_CARD_TYPE_OSAE:
888 card->dev = alloc_etherdev(0);
889 break;
890 case QETH_CARD_TYPE_IQD:
891 card->dev = alloc_netdev(0, "hsi%d", ether_setup);
892 break;
893 case QETH_CARD_TYPE_OSN:
894 card->dev = alloc_netdev(0, "osn%d", ether_setup);
895 card->dev->flags |= IFF_NOARP;
896 break;
897 default:
898 card->dev = alloc_etherdev(0);
899 }
900
901 if (!card->dev)
902 return -ENODEV;
903
904 card->dev->priv = card;
905 card->dev->tx_timeout = &qeth_tx_timeout;
906 card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
907 card->dev->open = qeth_l2_open;
908 card->dev->stop = qeth_l2_stop;
909 card->dev->hard_start_xmit = qeth_l2_hard_start_xmit;
910 card->dev->do_ioctl = qeth_l2_do_ioctl;
911 card->dev->get_stats = qeth_get_stats;
912 card->dev->change_mtu = qeth_change_mtu;
913 card->dev->set_multicast_list = qeth_l2_set_multicast_list;
914 card->dev->vlan_rx_kill_vid = qeth_l2_vlan_rx_kill_vid;
915 card->dev->vlan_rx_add_vid = qeth_l2_vlan_rx_add_vid;
916 card->dev->set_mac_address = qeth_l2_set_mac_address;
917 card->dev->mtu = card->info.initial_mtu;
918 if (card->info.type != QETH_CARD_TYPE_OSN)
919 SET_ETHTOOL_OPS(card->dev, &qeth_l2_ethtool_ops);
920 else
921 SET_ETHTOOL_OPS(card->dev, &qeth_l2_osn_ops);
922 card->dev->features |= NETIF_F_HW_VLAN_FILTER;
923 card->info.broadcast_capable = 1;
924 qeth_l2_request_initial_mac(card);
925 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
926 return register_netdev(card->dev);
927}
928
929static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
930{
931 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
932 int rc = 0;
933 enum qeth_card_states recover_flag;
934
935 BUG_ON(!card);
936 QETH_DBF_TEXT(setup, 2, "setonlin");
937 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
938
939 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
940 if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) {
941 PRINT_WARN("set_online of card %s interrupted by user!\n",
942 CARD_BUS_ID(card));
943 return -ERESTARTSYS;
944 }
945
946 recover_flag = card->state;
947 rc = ccw_device_set_online(CARD_RDEV(card));
948 if (rc) {
949 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
950 return -EIO;
951 }
952 rc = ccw_device_set_online(CARD_WDEV(card));
953 if (rc) {
954 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
955 return -EIO;
956 }
957 rc = ccw_device_set_online(CARD_DDEV(card));
958 if (rc) {
959 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
960 return -EIO;
961 }
962
963 rc = qeth_core_hardsetup_card(card);
964 if (rc) {
965 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
966 goto out_remove;
967 }
968
969 if (!card->dev && qeth_l2_setup_netdev(card))
970 goto out_remove;
971
972 if (card->info.type != QETH_CARD_TYPE_OSN)
973 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
974
975 card->state = CARD_STATE_HARDSETUP;
976 qeth_print_status_message(card);
977
978 /* softsetup */
979 QETH_DBF_TEXT(setup, 2, "softsetp");
980
981 rc = qeth_send_startlan(card);
982 if (rc) {
983 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
984 if (rc == 0xe080) {
985 PRINT_WARN("LAN on card %s if offline! "
986 "Waiting for STARTLAN from card.\n",
987 CARD_BUS_ID(card));
988 card->lan_online = 0;
989 }
990 return rc;
991 } else
992 card->lan_online = 1;
993
994 if (card->info.type != QETH_CARD_TYPE_OSN) {
995 qeth_set_large_send(card, card->options.large_send);
996 qeth_l2_process_vlans(card, 0);
997 }
998
999 netif_tx_disable(card->dev);
1000
1001 rc = qeth_init_qdio_queues(card);
1002 if (rc) {
1003 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
1004 goto out_remove;
1005 }
1006 card->state = CARD_STATE_SOFTSETUP;
1007 netif_carrier_on(card->dev);
1008
1009 qeth_set_allowed_threads(card, 0xffffffff, 0);
1010 if (recover_flag == CARD_STATE_RECOVER) {
1011 if (recovery_mode &&
1012 card->info.type != QETH_CARD_TYPE_OSN) {
1013 qeth_l2_open(card->dev);
1014 } else {
1015 rtnl_lock();
1016 dev_open(card->dev);
1017 rtnl_unlock();
1018 }
1019 /* this also sets saved unicast addresses */
1020 qeth_l2_set_multicast_list(card->dev);
1021 }
1022 /* let user_space know that device is online */
1023 kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
1024 return 0;
1025out_remove:
1026 card->use_hard_stop = 1;
1027 qeth_l2_stop_card(card, 0);
1028 ccw_device_set_offline(CARD_DDEV(card));
1029 ccw_device_set_offline(CARD_WDEV(card));
1030 ccw_device_set_offline(CARD_RDEV(card));
1031 if (recover_flag == CARD_STATE_RECOVER)
1032 card->state = CARD_STATE_RECOVER;
1033 else
1034 card->state = CARD_STATE_DOWN;
1035 return -ENODEV;
1036}
1037
1038static int qeth_l2_set_online(struct ccwgroup_device *gdev)
1039{
1040 return __qeth_l2_set_online(gdev, 0);
1041}
1042
1043static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
1044 int recovery_mode)
1045{
1046 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
1047 int rc = 0, rc2 = 0, rc3 = 0;
1048 enum qeth_card_states recover_flag;
1049
1050 QETH_DBF_TEXT(setup, 3, "setoffl");
1051 QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
1052
1053 if (card->dev && netif_carrier_ok(card->dev))
1054 netif_carrier_off(card->dev);
1055 recover_flag = card->state;
1056 if (qeth_l2_stop_card(card, recovery_mode) == -ERESTARTSYS) {
1057 PRINT_WARN("Stopping card %s interrupted by user!\n",
1058 CARD_BUS_ID(card));
1059 return -ERESTARTSYS;
1060 }
1061 rc = ccw_device_set_offline(CARD_DDEV(card));
1062 rc2 = ccw_device_set_offline(CARD_WDEV(card));
1063 rc3 = ccw_device_set_offline(CARD_RDEV(card));
1064 if (!rc)
1065 rc = (rc2) ? rc2 : rc3;
1066 if (rc)
1067 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
1068 if (recover_flag == CARD_STATE_UP)
1069 card->state = CARD_STATE_RECOVER;
1070 /* let user_space know that device is offline */
1071 kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
1072 return 0;
1073}
1074
1075static int qeth_l2_set_offline(struct ccwgroup_device *cgdev)
1076{
1077 return __qeth_l2_set_offline(cgdev, 0);
1078}
1079
1080static int qeth_l2_recover(void *ptr)
1081{
1082 struct qeth_card *card;
1083 int rc = 0;
1084
1085 card = (struct qeth_card *) ptr;
1086 QETH_DBF_TEXT(trace, 2, "recover1");
1087 QETH_DBF_HEX(trace, 2, &card, sizeof(void *));
1088 if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
1089 return 0;
1090 QETH_DBF_TEXT(trace, 2, "recover2");
1091 PRINT_WARN("Recovery of device %s started ...\n",
1092 CARD_BUS_ID(card));
1093 card->use_hard_stop = 1;
1094 __qeth_l2_set_offline(card->gdev, 1);
1095 rc = __qeth_l2_set_online(card->gdev, 1);
1096 /* don't run another scheduled recovery */
1097 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
1098 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
1099 if (!rc)
1100 PRINT_INFO("Device %s successfully recovered!\n",
1101 CARD_BUS_ID(card));
1102 else
1103 PRINT_INFO("Device %s could not be recovered!\n",
1104 CARD_BUS_ID(card));
1105 return 0;
1106}
1107
1108static int __init qeth_l2_init(void)
1109{
1110 PRINT_INFO("register layer 2 discipline\n");
1111 return 0;
1112}
1113
1114static void __exit qeth_l2_exit(void)
1115{
1116 PRINT_INFO("unregister layer 2 discipline\n");
1117}
1118
1119static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
1120{
1121 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
1122 qeth_qdio_clear_card(card, 0);
1123 qeth_clear_qdio_buffers(card);
1124}
1125
1126struct ccwgroup_driver qeth_l2_ccwgroup_driver = {
1127 .probe = qeth_l2_probe_device,
1128 .remove = qeth_l2_remove_device,
1129 .set_online = qeth_l2_set_online,
1130 .set_offline = qeth_l2_set_offline,
1131 .shutdown = qeth_l2_shutdown,
1132};
1133EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver);
1134
1135static int qeth_osn_send_control_data(struct qeth_card *card, int len,
1136 struct qeth_cmd_buffer *iob)
1137{
1138 unsigned long flags;
1139 int rc = 0;
1140
1141 QETH_DBF_TEXT(trace, 5, "osndctrd");
1142
1143 wait_event(card->wait_q,
1144 atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0);
1145 qeth_prepare_control_data(card, len, iob);
1146 QETH_DBF_TEXT(trace, 6, "osnoirqp");
1147 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
1148 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
1149 (addr_t) iob, 0, 0);
1150 spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
1151 if (rc) {
1152 PRINT_WARN("qeth_osn_send_control_data: "
1153 "ccw_device_start rc = %i\n", rc);
1154 QETH_DBF_TEXT_(trace, 2, " err%d", rc);
1155 qeth_release_buffer(iob->channel, iob);
1156 atomic_set(&card->write.irq_pending, 0);
1157 wake_up(&card->wait_q);
1158 }
1159 return rc;
1160}
1161
1162static int qeth_osn_send_ipa_cmd(struct qeth_card *card,
1163 struct qeth_cmd_buffer *iob, int data_len)
1164{
1165 u16 s1, s2;
1166
1167 QETH_DBF_TEXT(trace, 4, "osndipa");
1168
1169 qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
1170 s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
1171 s2 = (u16)data_len;
1172 memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
1173 memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
1174 memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
1175 memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
1176 return qeth_osn_send_control_data(card, s1, iob);
1177}
1178
1179int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
1180{
1181 struct qeth_cmd_buffer *iob;
1182 struct qeth_card *card;
1183 int rc;
1184
1185 QETH_DBF_TEXT(trace, 2, "osnsdmc");
1186 if (!dev)
1187 return -ENODEV;
1188 card = netdev_priv(dev);
1189 if (!card)
1190 return -ENODEV;
1191 if ((card->state != CARD_STATE_UP) &&
1192 (card->state != CARD_STATE_SOFTSETUP))
1193 return -ENODEV;
1194 iob = qeth_wait_for_buffer(&card->write);
1195 memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
1196 rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
1197 return rc;
1198}
1199EXPORT_SYMBOL(qeth_osn_assist);
1200
1201int qeth_osn_register(unsigned char *read_dev_no, struct net_device **dev,
1202 int (*assist_cb)(struct net_device *, void *),
1203 int (*data_cb)(struct sk_buff *))
1204{
1205 struct qeth_card *card;
1206
1207 QETH_DBF_TEXT(trace, 2, "osnreg");
1208 *dev = qeth_l2_netdev_by_devno(read_dev_no);
1209 if (*dev == NULL)
1210 return -ENODEV;
1211 card = netdev_priv(*dev);
1212 if (!card)
1213 return -ENODEV;
1214 if ((assist_cb == NULL) || (data_cb == NULL))
1215 return -EINVAL;
1216 card->osn_info.assist_cb = assist_cb;
1217 card->osn_info.data_cb = data_cb;
1218 return 0;
1219}
1220EXPORT_SYMBOL(qeth_osn_register);
1221
1222void qeth_osn_deregister(struct net_device *dev)
1223{
1224 struct qeth_card *card;
1225
1226 QETH_DBF_TEXT(trace, 2, "osndereg");
1227 if (!dev)
1228 return;
1229 card = netdev_priv(dev);
1230 if (!card)
1231 return;
1232 card->osn_info.assist_cb = NULL;
1233 card->osn_info.data_cb = NULL;
1234 return;
1235}
1236EXPORT_SYMBOL(qeth_osn_deregister);
1237
1238module_init(qeth_l2_init);
1239module_exit(qeth_l2_exit);
1240MODULE_AUTHOR("Frank Blaschka <frank.blaschka@de.ibm.com>");
1241MODULE_DESCRIPTION("qeth layer 2 discipline");
1242MODULE_LICENSE("GPL");
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h
new file mode 100644
index 000000000000..f639cc3af22b
--- /dev/null
+++ b/drivers/s390/net/qeth_l3.h
@@ -0,0 +1,76 @@
1/*
2 * drivers/s390/net/qeth_l3.h
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
11#ifndef __QETH_L3_H__
12#define __QETH_L3_H__
13
14#include "qeth_core.h"
15
16#define QETH_DBF_TEXT_(name, level, text...) \
17 do { \
18 if (qeth_dbf_passes(qeth_dbf_##name, level)) { \
19 char *dbf_txt_buf = get_cpu_var(qeth_l3_dbf_txt_buf); \
20 sprintf(dbf_txt_buf, text); \
21 debug_text_event(qeth_dbf_##name, level, dbf_txt_buf); \
22 put_cpu_var(qeth_l3_dbf_txt_buf); \
23 } \
24 } while (0)
25
26DECLARE_PER_CPU(char[256], qeth_l3_dbf_txt_buf);
27
28struct qeth_ipaddr {
29 struct list_head entry;
30 enum qeth_ip_types type;
31 enum qeth_ipa_setdelip_flags set_flags;
32 enum qeth_ipa_setdelip_flags del_flags;
33 int is_multicast;
34 int users;
35 enum qeth_prot_versions proto;
36 unsigned char mac[OSA_ADDR_LEN];
37 union {
38 struct {
39 unsigned int addr;
40 unsigned int mask;
41 } a4;
42 struct {
43 struct in6_addr addr;
44 unsigned int pfxlen;
45 } a6;
46 } u;
47};
48
49struct qeth_ipato_entry {
50 struct list_head entry;
51 enum qeth_prot_versions proto;
52 char addr[16];
53 int mask_bits;
54};
55
56
57void qeth_l3_ipaddr4_to_string(const __u8 *, char *);
58int qeth_l3_string_to_ipaddr4(const char *, __u8 *);
59void qeth_l3_ipaddr6_to_string(const __u8 *, char *);
60int qeth_l3_string_to_ipaddr6(const char *, __u8 *);
61void qeth_l3_ipaddr_to_string(enum qeth_prot_versions, const __u8 *, char *);
62int qeth_l3_string_to_ipaddr(const char *, enum qeth_prot_versions, __u8 *);
63int qeth_l3_create_device_attributes(struct device *);
64void qeth_l3_remove_device_attributes(struct device *);
65int qeth_l3_setrouting_v4(struct qeth_card *);
66int qeth_l3_setrouting_v6(struct qeth_card *);
67int qeth_l3_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *);
68void qeth_l3_del_ipato_entry(struct qeth_card *, enum qeth_prot_versions,
69 u8 *, int);
70int qeth_l3_add_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
71void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
72int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
73void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
74 const u8 *);
75
76#endif /* __QETH_L3_H__ */
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
new file mode 100644
index 000000000000..a856cb47fc78
--- /dev/null
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -0,0 +1,3391 @@
1/*
2 * drivers/s390/net/qeth_l3_main.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/string.h>
14#include <linux/errno.h>
15#include <linux/kernel.h>
16#include <linux/etherdevice.h>
17#include <linux/mii.h>
18#include <linux/ip.h>
19#include <linux/reboot.h>
20#include <linux/inetdevice.h>
21#include <linux/igmp.h>
22
23#include <net/ip.h>
24#include <net/arp.h>
25
26#include <asm/s390_rdev.h>
27
28#include "qeth_l3.h"
29#include "qeth_core_offl.h"
30
31DEFINE_PER_CPU(char[256], qeth_l3_dbf_txt_buf);
32
33static int qeth_l3_set_offline(struct ccwgroup_device *);
34static int qeth_l3_recover(void *);
35static int qeth_l3_stop(struct net_device *);
36static void qeth_l3_set_multicast_list(struct net_device *);
37static int qeth_l3_neigh_setup(struct net_device *, struct neigh_parms *);
38static int qeth_l3_register_addr_entry(struct qeth_card *,
39 struct qeth_ipaddr *);
40static int qeth_l3_deregister_addr_entry(struct qeth_card *,
41 struct qeth_ipaddr *);
42static int __qeth_l3_set_online(struct ccwgroup_device *, int);
43static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
44
45
46static int qeth_l3_isxdigit(char *buf)
47{
48 while (*buf) {
49 if (!isxdigit(*buf++))
50 return 0;
51 }
52 return 1;
53}
54
55void qeth_l3_ipaddr4_to_string(const __u8 *addr, char *buf)
56{
57 sprintf(buf, "%i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]);
58}
59
60int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr)
61{
62 int count = 0, rc = 0;
63 int in[4];
64 char c;
65
66 rc = sscanf(buf, "%u.%u.%u.%u%c",
67 &in[0], &in[1], &in[2], &in[3], &c);
68 if (rc != 4 && (rc != 5 || c != '\n'))
69 return -EINVAL;
70 for (count = 0; count < 4; count++) {
71 if (in[count] > 255)
72 return -EINVAL;
73 addr[count] = in[count];
74 }
75 return 0;
76}
77
78void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf)
79{
80 sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x"
81 ":%02x%02x:%02x%02x:%02x%02x:%02x%02x",
82 addr[0], addr[1], addr[2], addr[3],
83 addr[4], addr[5], addr[6], addr[7],
84 addr[8], addr[9], addr[10], addr[11],
85 addr[12], addr[13], addr[14], addr[15]);
86}
87
88int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr)
89{
90 const char *end, *end_tmp, *start;
91 __u16 *in;
92 char num[5];
93 int num2, cnt, out, found, save_cnt;
94 unsigned short in_tmp[8] = {0, };
95
96 cnt = out = found = save_cnt = num2 = 0;
97 end = start = buf;
98 in = (__u16 *) addr;
99 memset(in, 0, 16);
100 while (*end) {
101 end = strchr(start, ':');
102 if (end == NULL) {
103 end = buf + strlen(buf);
104 end_tmp = strchr(start, '\n');
105 if (end_tmp != NULL)
106 end = end_tmp;
107 out = 1;
108 }
109 if ((end - start)) {
110 memset(num, 0, 5);
111 if ((end - start) > 4)
112 return -EINVAL;
113 memcpy(num, start, end - start);
114 if (!qeth_l3_isxdigit(num))
115 return -EINVAL;
116 sscanf(start, "%x", &num2);
117 if (found)
118 in_tmp[save_cnt++] = num2;
119 else
120 in[cnt++] = num2;
121 if (out)
122 break;
123 } else {
124 if (found)
125 return -EINVAL;
126 found = 1;
127 }
128 start = ++end;
129 }
130 if (cnt + save_cnt > 8)
131 return -EINVAL;
132 cnt = 7;
133 while (save_cnt)
134 in[cnt--] = in_tmp[--save_cnt];
135 return 0;
136}
137
138void qeth_l3_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
139 char *buf)
140{
141 if (proto == QETH_PROT_IPV4)
142 qeth_l3_ipaddr4_to_string(addr, buf);
143 else if (proto == QETH_PROT_IPV6)
144 qeth_l3_ipaddr6_to_string(addr, buf);
145}
146
147int qeth_l3_string_to_ipaddr(const char *buf, enum qeth_prot_versions proto,
148 __u8 *addr)
149{
150 if (proto == QETH_PROT_IPV4)
151 return qeth_l3_string_to_ipaddr4(buf, addr);
152 else if (proto == QETH_PROT_IPV6)
153 return qeth_l3_string_to_ipaddr6(buf, addr);
154 else
155 return -EINVAL;
156}
157
158static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
159{
160 int i, j;
161 u8 octet;
162
163 for (i = 0; i < len; ++i) {
164 octet = addr[i];
165 for (j = 7; j >= 0; --j) {
166 bits[i*8 + j] = octet & 1;
167 octet >>= 1;
168 }
169 }
170}
171
172static int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
173 struct qeth_ipaddr *addr)
174{
175 struct qeth_ipato_entry *ipatoe;
176 u8 addr_bits[128] = {0, };
177 u8 ipatoe_bits[128] = {0, };
178 int rc = 0;
179
180 if (!card->ipato.enabled)
181 return 0;
182
183 qeth_l3_convert_addr_to_bits((u8 *) &addr->u, addr_bits,
184 (addr->proto == QETH_PROT_IPV4)? 4:16);
185 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
186 if (addr->proto != ipatoe->proto)
187 continue;
188 qeth_l3_convert_addr_to_bits(ipatoe->addr, ipatoe_bits,
189 (ipatoe->proto == QETH_PROT_IPV4) ?
190 4 : 16);
191 if (addr->proto == QETH_PROT_IPV4)
192 rc = !memcmp(addr_bits, ipatoe_bits,
193 min(32, ipatoe->mask_bits));
194 else
195 rc = !memcmp(addr_bits, ipatoe_bits,
196 min(128, ipatoe->mask_bits));
197 if (rc)
198 break;
199 }
200 /* invert? */
201 if ((addr->proto == QETH_PROT_IPV4) && card->ipato.invert4)
202 rc = !rc;
203 else if ((addr->proto == QETH_PROT_IPV6) && card->ipato.invert6)
204 rc = !rc;
205
206 return rc;
207}
208
209/*
210 * Add IP to be added to todo list. If there is already an "add todo"
211 * in this list we just incremenent the reference count.
212 * Returns 0 if we just incremented reference count.
213 */
214static int __qeth_l3_insert_ip_todo(struct qeth_card *card,
215 struct qeth_ipaddr *addr, int add)
216{
217 struct qeth_ipaddr *tmp, *t;
218 int found = 0;
219
220 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
221 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
222 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
223 return 0;
224 if ((tmp->proto == QETH_PROT_IPV4) &&
225 (addr->proto == QETH_PROT_IPV4) &&
226 (tmp->type == addr->type) &&
227 (tmp->is_multicast == addr->is_multicast) &&
228 (tmp->u.a4.addr == addr->u.a4.addr) &&
229 (tmp->u.a4.mask == addr->u.a4.mask)) {
230 found = 1;
231 break;
232 }
233 if ((tmp->proto == QETH_PROT_IPV6) &&
234 (addr->proto == QETH_PROT_IPV6) &&
235 (tmp->type == addr->type) &&
236 (tmp->is_multicast == addr->is_multicast) &&
237 (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) &&
238 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
239 sizeof(struct in6_addr)) == 0)) {
240 found = 1;
241 break;
242 }
243 }
244 if (found) {
245 if (addr->users != 0)
246 tmp->users += addr->users;
247 else
248 tmp->users += add ? 1 : -1;
249 if (tmp->users == 0) {
250 list_del(&tmp->entry);
251 kfree(tmp);
252 }
253 return 0;
254 } else {
255 if (addr->type == QETH_IP_TYPE_DEL_ALL_MC)
256 list_add(&addr->entry, card->ip_tbd_list);
257 else {
258 if (addr->users == 0)
259 addr->users += add ? 1 : -1;
260 if (add && (addr->type == QETH_IP_TYPE_NORMAL) &&
261 qeth_l3_is_addr_covered_by_ipato(card, addr)) {
262 QETH_DBF_TEXT(trace, 2, "tkovaddr");
263 addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
264 }
265 list_add_tail(&addr->entry, card->ip_tbd_list);
266 }
267 return 1;
268 }
269}
270
271static int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
272{
273 unsigned long flags;
274 int rc = 0;
275
276 QETH_DBF_TEXT(trace, 4, "delip");
277
278 if (addr->proto == QETH_PROT_IPV4)
279 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
280 else {
281 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
282 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
283 }
284 spin_lock_irqsave(&card->ip_lock, flags);
285 rc = __qeth_l3_insert_ip_todo(card, addr, 0);
286 spin_unlock_irqrestore(&card->ip_lock, flags);
287 return rc;
288}
289
290static int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
291{
292 unsigned long flags;
293 int rc = 0;
294
295 QETH_DBF_TEXT(trace, 4, "addip");
296 if (addr->proto == QETH_PROT_IPV4)
297 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
298 else {
299 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
300 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
301 }
302 spin_lock_irqsave(&card->ip_lock, flags);
303 rc = __qeth_l3_insert_ip_todo(card, addr, 1);
304 spin_unlock_irqrestore(&card->ip_lock, flags);
305 return rc;
306}
307
308
309static struct qeth_ipaddr *qeth_l3_get_addr_buffer(
310 enum qeth_prot_versions prot)
311{
312 struct qeth_ipaddr *addr;
313
314 addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
315 if (addr == NULL) {
316 PRINT_WARN("Not enough memory to add address\n");
317 return NULL;
318 }
319 addr->type = QETH_IP_TYPE_NORMAL;
320 addr->proto = prot;
321 return addr;
322}
323
324static void qeth_l3_delete_mc_addresses(struct qeth_card *card)
325{
326 struct qeth_ipaddr *iptodo;
327 unsigned long flags;
328
329 QETH_DBF_TEXT(trace, 4, "delmc");
330 iptodo = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
331 if (!iptodo) {
332 QETH_DBF_TEXT(trace, 2, "dmcnomem");
333 return;
334 }
335 iptodo->type = QETH_IP_TYPE_DEL_ALL_MC;
336 spin_lock_irqsave(&card->ip_lock, flags);
337 if (!__qeth_l3_insert_ip_todo(card, iptodo, 0))
338 kfree(iptodo);
339 spin_unlock_irqrestore(&card->ip_lock, flags);
340}
341
342/*
343 * Add/remove address to/from card's ip list, i.e. try to add or remove
344 * reference to/from an IP address that is already registered on the card.
345 * Returns:
346 * 0 address was on card and its reference count has been adjusted,
347 * but is still > 0, so nothing has to be done
348 * also returns 0 if card was not on card and the todo was to delete
349 * the address -> there is also nothing to be done
350 * 1 address was not on card and the todo is to add it to the card's ip
351 * list
352 * -1 address was on card and its reference count has been decremented
353 * to <= 0 by the todo -> address must be removed from card
354 */
355static int __qeth_l3_ref_ip_on_card(struct qeth_card *card,
356 struct qeth_ipaddr *todo, struct qeth_ipaddr **__addr)
357{
358 struct qeth_ipaddr *addr;
359 int found = 0;
360
361 list_for_each_entry(addr, &card->ip_list, entry) {
362 if ((addr->proto == QETH_PROT_IPV4) &&
363 (todo->proto == QETH_PROT_IPV4) &&
364 (addr->type == todo->type) &&
365 (addr->u.a4.addr == todo->u.a4.addr) &&
366 (addr->u.a4.mask == todo->u.a4.mask)) {
367 found = 1;
368 break;
369 }
370 if ((addr->proto == QETH_PROT_IPV6) &&
371 (todo->proto == QETH_PROT_IPV6) &&
372 (addr->type == todo->type) &&
373 (addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&
374 (memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
375 sizeof(struct in6_addr)) == 0)) {
376 found = 1;
377 break;
378 }
379 }
380 if (found) {
381 addr->users += todo->users;
382 if (addr->users <= 0) {
383 *__addr = addr;
384 return -1;
385 } else {
386 /* for VIPA and RXIP limit refcount to 1 */
387 if (addr->type != QETH_IP_TYPE_NORMAL)
388 addr->users = 1;
389 return 0;
390 }
391 }
392 if (todo->users > 0) {
393 /* for VIPA and RXIP limit refcount to 1 */
394 if (todo->type != QETH_IP_TYPE_NORMAL)
395 todo->users = 1;
396 return 1;
397 } else
398 return 0;
399}
400
401static void __qeth_l3_delete_all_mc(struct qeth_card *card,
402 unsigned long *flags)
403{
404 struct qeth_ipaddr *addr, *tmp;
405 int rc;
406again:
407 list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
408 if (addr->is_multicast) {
409 list_del(&addr->entry);
410 spin_unlock_irqrestore(&card->ip_lock, *flags);
411 rc = qeth_l3_deregister_addr_entry(card, addr);
412 spin_lock_irqsave(&card->ip_lock, *flags);
413 if (!rc) {
414 kfree(addr);
415 goto again;
416 } else
417 list_add(&addr->entry, &card->ip_list);
418 }
419 }
420}
421
422static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
423{
424 struct list_head *tbd_list;
425 struct qeth_ipaddr *todo, *addr;
426 unsigned long flags;
427 int rc;
428
429 QETH_DBF_TEXT(trace, 2, "sdiplist");
430 QETH_DBF_HEX(trace, 2, &card, sizeof(void *));
431
432 spin_lock_irqsave(&card->ip_lock, flags);
433 tbd_list = card->ip_tbd_list;
434 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
435 if (!card->ip_tbd_list) {
436 QETH_DBF_TEXT(trace, 0, "silnomem");
437 card->ip_tbd_list = tbd_list;
438 spin_unlock_irqrestore(&card->ip_lock, flags);
439 return;
440 } else
441 INIT_LIST_HEAD(card->ip_tbd_list);
442
443 while (!list_empty(tbd_list)) {
444 todo = list_entry(tbd_list->next, struct qeth_ipaddr, entry);
445 list_del(&todo->entry);
446 if (todo->type == QETH_IP_TYPE_DEL_ALL_MC) {
447 __qeth_l3_delete_all_mc(card, &flags);
448 kfree(todo);
449 continue;
450 }
451 rc = __qeth_l3_ref_ip_on_card(card, todo, &addr);
452 if (rc == 0) {
453 /* nothing to be done; only adjusted refcount */
454 kfree(todo);
455 } else if (rc == 1) {
456 /* new entry to be added to on-card list */
457 spin_unlock_irqrestore(&card->ip_lock, flags);
458 rc = qeth_l3_register_addr_entry(card, todo);
459 spin_lock_irqsave(&card->ip_lock, flags);
460 if (!rc)
461 list_add_tail(&todo->entry, &card->ip_list);
462 else
463 kfree(todo);
464 } else if (rc == -1) {
465 /* on-card entry to be removed */
466 list_del_init(&addr->entry);
467 spin_unlock_irqrestore(&card->ip_lock, flags);
468 rc = qeth_l3_deregister_addr_entry(card, addr);
469 spin_lock_irqsave(&card->ip_lock, flags);
470 if (!rc)
471 kfree(addr);
472 else
473 list_add_tail(&addr->entry, &card->ip_list);
474 kfree(todo);
475 }
476 }
477 spin_unlock_irqrestore(&card->ip_lock, flags);
478 kfree(tbd_list);
479}
480
481static void qeth_l3_clear_ip_list(struct qeth_card *card, int clean,
482 int recover)
483{
484 struct qeth_ipaddr *addr, *tmp;
485 unsigned long flags;
486
487 QETH_DBF_TEXT(trace, 4, "clearip");
488 spin_lock_irqsave(&card->ip_lock, flags);
489 /* clear todo list */
490 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) {
491 list_del(&addr->entry);
492 kfree(addr);
493 }
494
495 while (!list_empty(&card->ip_list)) {
496 addr = list_entry(card->ip_list.next,
497 struct qeth_ipaddr, entry);
498 list_del_init(&addr->entry);
499 if (clean) {
500 spin_unlock_irqrestore(&card->ip_lock, flags);
501 qeth_l3_deregister_addr_entry(card, addr);
502 spin_lock_irqsave(&card->ip_lock, flags);
503 }
504 if (!recover || addr->is_multicast) {
505 kfree(addr);
506 continue;
507 }
508 list_add_tail(&addr->entry, card->ip_tbd_list);
509 }
510 spin_unlock_irqrestore(&card->ip_lock, flags);
511}
512
513static int qeth_l3_address_exists_in_list(struct list_head *list,
514 struct qeth_ipaddr *addr, int same_type)
515{
516 struct qeth_ipaddr *tmp;
517
518 list_for_each_entry(tmp, list, entry) {
519 if ((tmp->proto == QETH_PROT_IPV4) &&
520 (addr->proto == QETH_PROT_IPV4) &&
521 ((same_type && (tmp->type == addr->type)) ||
522 (!same_type && (tmp->type != addr->type))) &&
523 (tmp->u.a4.addr == addr->u.a4.addr))
524 return 1;
525
526 if ((tmp->proto == QETH_PROT_IPV6) &&
527 (addr->proto == QETH_PROT_IPV6) &&
528 ((same_type && (tmp->type == addr->type)) ||
529 (!same_type && (tmp->type != addr->type))) &&
530 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
531 sizeof(struct in6_addr)) == 0))
532 return 1;
533
534 }
535 return 0;
536}
537
538static int qeth_l3_send_setdelmc(struct qeth_card *card,
539 struct qeth_ipaddr *addr, int ipacmd)
540{
541 int rc;
542 struct qeth_cmd_buffer *iob;
543 struct qeth_ipa_cmd *cmd;
544
545 QETH_DBF_TEXT(trace, 4, "setdelmc");
546
547 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
548 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
549 memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN);
550 if (addr->proto == QETH_PROT_IPV6)
551 memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr,
552 sizeof(struct in6_addr));
553 else
554 memcpy(&cmd->data.setdelipm.ip4, &addr->u.a4.addr, 4);
555
556 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
557
558 return rc;
559}
560
561static void qeth_l3_fill_netmask(u8 *netmask, unsigned int len)
562{
563 int i, j;
564 for (i = 0; i < 16; i++) {
565 j = (len) - (i * 8);
566 if (j >= 8)
567 netmask[i] = 0xff;
568 else if (j > 0)
569 netmask[i] = (u8)(0xFF00 >> j);
570 else
571 netmask[i] = 0;
572 }
573}
574
575static int qeth_l3_send_setdelip(struct qeth_card *card,
576 struct qeth_ipaddr *addr, int ipacmd, unsigned int flags)
577{
578 int rc;
579 struct qeth_cmd_buffer *iob;
580 struct qeth_ipa_cmd *cmd;
581 __u8 netmask[16];
582
583 QETH_DBF_TEXT(trace, 4, "setdelip");
584 QETH_DBF_TEXT_(trace, 4, "flags%02X", flags);
585
586 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
587 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
588 if (addr->proto == QETH_PROT_IPV6) {
589 memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr,
590 sizeof(struct in6_addr));
591 qeth_l3_fill_netmask(netmask, addr->u.a6.pfxlen);
592 memcpy(cmd->data.setdelip6.mask, netmask,
593 sizeof(struct in6_addr));
594 cmd->data.setdelip6.flags = flags;
595 } else {
596 memcpy(cmd->data.setdelip4.ip_addr, &addr->u.a4.addr, 4);
597 memcpy(cmd->data.setdelip4.mask, &addr->u.a4.mask, 4);
598 cmd->data.setdelip4.flags = flags;
599 }
600
601 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
602
603 return rc;
604}
605
606static int qeth_l3_send_setrouting(struct qeth_card *card,
607 enum qeth_routing_types type, enum qeth_prot_versions prot)
608{
609 int rc;
610 struct qeth_ipa_cmd *cmd;
611 struct qeth_cmd_buffer *iob;
612
613 QETH_DBF_TEXT(trace, 4, "setroutg");
614 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot);
615 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
616 cmd->data.setrtg.type = (type);
617 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
618
619 return rc;
620}
621
622static void qeth_l3_correct_routing_type(struct qeth_card *card,
623 enum qeth_routing_types *type, enum qeth_prot_versions prot)
624{
625 if (card->info.type == QETH_CARD_TYPE_IQD) {
626 switch (*type) {
627 case NO_ROUTER:
628 case PRIMARY_CONNECTOR:
629 case SECONDARY_CONNECTOR:
630 case MULTICAST_ROUTER:
631 return;
632 default:
633 goto out_inval;
634 }
635 } else {
636 switch (*type) {
637 case NO_ROUTER:
638 case PRIMARY_ROUTER:
639 case SECONDARY_ROUTER:
640 return;
641 case MULTICAST_ROUTER:
642 if (qeth_is_ipafunc_supported(card, prot,
643 IPA_OSA_MC_ROUTER))
644 return;
645 default:
646 goto out_inval;
647 }
648 }
649out_inval:
650 PRINT_WARN("Routing type '%s' not supported for interface %s.\n"
651 "Router status set to 'no router'.\n",
652 ((*type == PRIMARY_ROUTER)? "primary router" :
653 (*type == SECONDARY_ROUTER)? "secondary router" :
654 (*type == PRIMARY_CONNECTOR)? "primary connector" :
655 (*type == SECONDARY_CONNECTOR)? "secondary connector" :
656 (*type == MULTICAST_ROUTER)? "multicast router" :
657 "unknown"),
658 card->dev->name);
659 *type = NO_ROUTER;
660}
661
662int qeth_l3_setrouting_v4(struct qeth_card *card)
663{
664 int rc;
665
666 QETH_DBF_TEXT(trace, 3, "setrtg4");
667
668 qeth_l3_correct_routing_type(card, &card->options.route4.type,
669 QETH_PROT_IPV4);
670
671 rc = qeth_l3_send_setrouting(card, card->options.route4.type,
672 QETH_PROT_IPV4);
673 if (rc) {
674 card->options.route4.type = NO_ROUTER;
675 PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
676 "Type set to 'no router'.\n",
677 rc, QETH_CARD_IFNAME(card));
678 }
679 return rc;
680}
681
682int qeth_l3_setrouting_v6(struct qeth_card *card)
683{
684 int rc = 0;
685
686 QETH_DBF_TEXT(trace, 3, "setrtg6");
687#ifdef CONFIG_QETH_IPV6
688
689 if (!qeth_is_supported(card, IPA_IPV6))
690 return 0;
691 qeth_l3_correct_routing_type(card, &card->options.route6.type,
692 QETH_PROT_IPV6);
693
694 rc = qeth_l3_send_setrouting(card, card->options.route6.type,
695 QETH_PROT_IPV6);
696 if (rc) {
697 card->options.route6.type = NO_ROUTER;
698 PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
699 "Type set to 'no router'.\n",
700 rc, QETH_CARD_IFNAME(card));
701 }
702#endif
703 return rc;
704}
705
706/*
707 * IP address takeover related functions
708 */
709static void qeth_l3_clear_ipato_list(struct qeth_card *card)
710{
711
712 struct qeth_ipato_entry *ipatoe, *tmp;
713 unsigned long flags;
714
715 spin_lock_irqsave(&card->ip_lock, flags);
716 list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry) {
717 list_del(&ipatoe->entry);
718 kfree(ipatoe);
719 }
720 spin_unlock_irqrestore(&card->ip_lock, flags);
721}
722
723int qeth_l3_add_ipato_entry(struct qeth_card *card,
724 struct qeth_ipato_entry *new)
725{
726 struct qeth_ipato_entry *ipatoe;
727 unsigned long flags;
728 int rc = 0;
729
730 QETH_DBF_TEXT(trace, 2, "addipato");
731 spin_lock_irqsave(&card->ip_lock, flags);
732 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
733 if (ipatoe->proto != new->proto)
734 continue;
735 if (!memcmp(ipatoe->addr, new->addr,
736 (ipatoe->proto == QETH_PROT_IPV4)? 4:16) &&
737 (ipatoe->mask_bits == new->mask_bits)) {
738 PRINT_WARN("ipato entry already exists!\n");
739 rc = -EEXIST;
740 break;
741 }
742 }
743 if (!rc)
744 list_add_tail(&new->entry, &card->ipato.entries);
745
746 spin_unlock_irqrestore(&card->ip_lock, flags);
747 return rc;
748}
749
750void qeth_l3_del_ipato_entry(struct qeth_card *card,
751 enum qeth_prot_versions proto, u8 *addr, int mask_bits)
752{
753 struct qeth_ipato_entry *ipatoe, *tmp;
754 unsigned long flags;
755
756 QETH_DBF_TEXT(trace, 2, "delipato");
757 spin_lock_irqsave(&card->ip_lock, flags);
758 list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry) {
759 if (ipatoe->proto != proto)
760 continue;
761 if (!memcmp(ipatoe->addr, addr,
762 (proto == QETH_PROT_IPV4)? 4:16) &&
763 (ipatoe->mask_bits == mask_bits)) {
764 list_del(&ipatoe->entry);
765 kfree(ipatoe);
766 }
767 }
768 spin_unlock_irqrestore(&card->ip_lock, flags);
769}
770
771/*
772 * VIPA related functions
773 */
774int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
775 const u8 *addr)
776{
777 struct qeth_ipaddr *ipaddr;
778 unsigned long flags;
779 int rc = 0;
780
781 ipaddr = qeth_l3_get_addr_buffer(proto);
782 if (ipaddr) {
783 if (proto == QETH_PROT_IPV4) {
784 QETH_DBF_TEXT(trace, 2, "addvipa4");
785 memcpy(&ipaddr->u.a4.addr, addr, 4);
786 ipaddr->u.a4.mask = 0;
787 } else if (proto == QETH_PROT_IPV6) {
788 QETH_DBF_TEXT(trace, 2, "addvipa6");
789 memcpy(&ipaddr->u.a6.addr, addr, 16);
790 ipaddr->u.a6.pfxlen = 0;
791 }
792 ipaddr->type = QETH_IP_TYPE_VIPA;
793 ipaddr->set_flags = QETH_IPA_SETIP_VIPA_FLAG;
794 ipaddr->del_flags = QETH_IPA_DELIP_VIPA_FLAG;
795 } else
796 return -ENOMEM;
797 spin_lock_irqsave(&card->ip_lock, flags);
798 if (qeth_l3_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
799 qeth_l3_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
800 rc = -EEXIST;
801 spin_unlock_irqrestore(&card->ip_lock, flags);
802 if (rc) {
803 PRINT_WARN("Cannot add VIPA. Address already exists!\n");
804 return rc;
805 }
806 if (!qeth_l3_add_ip(card, ipaddr))
807 kfree(ipaddr);
808 qeth_l3_set_ip_addr_list(card);
809 return rc;
810}
811
812void qeth_l3_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
813 const u8 *addr)
814{
815 struct qeth_ipaddr *ipaddr;
816
817 ipaddr = qeth_l3_get_addr_buffer(proto);
818 if (ipaddr) {
819 if (proto == QETH_PROT_IPV4) {
820 QETH_DBF_TEXT(trace, 2, "delvipa4");
821 memcpy(&ipaddr->u.a4.addr, addr, 4);
822 ipaddr->u.a4.mask = 0;
823 } else if (proto == QETH_PROT_IPV6) {
824 QETH_DBF_TEXT(trace, 2, "delvipa6");
825 memcpy(&ipaddr->u.a6.addr, addr, 16);
826 ipaddr->u.a6.pfxlen = 0;
827 }
828 ipaddr->type = QETH_IP_TYPE_VIPA;
829 } else
830 return;
831 if (!qeth_l3_delete_ip(card, ipaddr))
832 kfree(ipaddr);
833 qeth_l3_set_ip_addr_list(card);
834}
835
836/*
837 * proxy ARP related functions
838 */
839int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
840 const u8 *addr)
841{
842 struct qeth_ipaddr *ipaddr;
843 unsigned long flags;
844 int rc = 0;
845
846 ipaddr = qeth_l3_get_addr_buffer(proto);
847 if (ipaddr) {
848 if (proto == QETH_PROT_IPV4) {
849 QETH_DBF_TEXT(trace, 2, "addrxip4");
850 memcpy(&ipaddr->u.a4.addr, addr, 4);
851 ipaddr->u.a4.mask = 0;
852 } else if (proto == QETH_PROT_IPV6) {
853 QETH_DBF_TEXT(trace, 2, "addrxip6");
854 memcpy(&ipaddr->u.a6.addr, addr, 16);
855 ipaddr->u.a6.pfxlen = 0;
856 }
857 ipaddr->type = QETH_IP_TYPE_RXIP;
858 ipaddr->set_flags = QETH_IPA_SETIP_TAKEOVER_FLAG;
859 ipaddr->del_flags = 0;
860 } else
861 return -ENOMEM;
862 spin_lock_irqsave(&card->ip_lock, flags);
863 if (qeth_l3_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
864 qeth_l3_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
865 rc = -EEXIST;
866 spin_unlock_irqrestore(&card->ip_lock, flags);
867 if (rc) {
868 PRINT_WARN("Cannot add RXIP. Address already exists!\n");
869 return rc;
870 }
871 if (!qeth_l3_add_ip(card, ipaddr))
872 kfree(ipaddr);
873 qeth_l3_set_ip_addr_list(card);
874 return 0;
875}
876
877void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
878 const u8 *addr)
879{
880 struct qeth_ipaddr *ipaddr;
881
882 ipaddr = qeth_l3_get_addr_buffer(proto);
883 if (ipaddr) {
884 if (proto == QETH_PROT_IPV4) {
885 QETH_DBF_TEXT(trace, 2, "addrxip4");
886 memcpy(&ipaddr->u.a4.addr, addr, 4);
887 ipaddr->u.a4.mask = 0;
888 } else if (proto == QETH_PROT_IPV6) {
889 QETH_DBF_TEXT(trace, 2, "addrxip6");
890 memcpy(&ipaddr->u.a6.addr, addr, 16);
891 ipaddr->u.a6.pfxlen = 0;
892 }
893 ipaddr->type = QETH_IP_TYPE_RXIP;
894 } else
895 return;
896 if (!qeth_l3_delete_ip(card, ipaddr))
897 kfree(ipaddr);
898 qeth_l3_set_ip_addr_list(card);
899}
900
901static int qeth_l3_register_addr_entry(struct qeth_card *card,
902 struct qeth_ipaddr *addr)
903{
904 char buf[50];
905 int rc = 0;
906 int cnt = 3;
907
908 if (addr->proto == QETH_PROT_IPV4) {
909 QETH_DBF_TEXT(trace, 2, "setaddr4");
910 QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
911 } else if (addr->proto == QETH_PROT_IPV6) {
912 QETH_DBF_TEXT(trace, 2, "setaddr6");
913 QETH_DBF_HEX(trace, 3, &addr->u.a6.addr, 8);
914 QETH_DBF_HEX(trace, 3, ((char *)&addr->u.a6.addr) + 8, 8);
915 } else {
916 QETH_DBF_TEXT(trace, 2, "setaddr?");
917 QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
918 }
919 do {
920 if (addr->is_multicast)
921 rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_SETIPM);
922 else
923 rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP,
924 addr->set_flags);
925 if (rc)
926 QETH_DBF_TEXT(trace, 2, "failed");
927 } while ((--cnt > 0) && rc);
928 if (rc) {
929 QETH_DBF_TEXT(trace, 2, "FAILED");
930 qeth_l3_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf);
931 PRINT_WARN("Could not register IP address %s (rc=0x%x/%d)\n",
932 buf, rc, rc);
933 }
934 return rc;
935}
936
937static int qeth_l3_deregister_addr_entry(struct qeth_card *card,
938 struct qeth_ipaddr *addr)
939{
940 int rc = 0;
941
942 if (addr->proto == QETH_PROT_IPV4) {
943 QETH_DBF_TEXT(trace, 2, "deladdr4");
944 QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
945 } else if (addr->proto == QETH_PROT_IPV6) {
946 QETH_DBF_TEXT(trace, 2, "deladdr6");
947 QETH_DBF_HEX(trace, 3, &addr->u.a6.addr, 8);
948 QETH_DBF_HEX(trace, 3, ((char *)&addr->u.a6.addr) + 8, 8);
949 } else {
950 QETH_DBF_TEXT(trace, 2, "deladdr?");
951 QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
952 }
953 if (addr->is_multicast)
954 rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_DELIPM);
955 else
956 rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP,
957 addr->del_flags);
958 if (rc) {
959 QETH_DBF_TEXT(trace, 2, "failed");
960 /* TODO: re-activate this warning as soon as we have a
961 * clean mirco code
962 qeth_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf);
963 PRINT_WARN("Could not deregister IP address %s (rc=%x)\n",
964 buf, rc);
965 */
966 }
967
968 return rc;
969}
970
971static inline u8 qeth_l3_get_qeth_hdr_flags4(int cast_type)
972{
973 if (cast_type == RTN_MULTICAST)
974 return QETH_CAST_MULTICAST;
975 if (cast_type == RTN_BROADCAST)
976 return QETH_CAST_BROADCAST;
977 return QETH_CAST_UNICAST;
978}
979
980static inline u8 qeth_l3_get_qeth_hdr_flags6(int cast_type)
981{
982 u8 ct = QETH_HDR_PASSTHRU | QETH_HDR_IPV6;
983 if (cast_type == RTN_MULTICAST)
984 return ct | QETH_CAST_MULTICAST;
985 if (cast_type == RTN_ANYCAST)
986 return ct | QETH_CAST_ANYCAST;
987 if (cast_type == RTN_BROADCAST)
988 return ct | QETH_CAST_BROADCAST;
989 return ct | QETH_CAST_UNICAST;
990}
991
992static int qeth_l3_send_setadp_mode(struct qeth_card *card, __u32 command,
993 __u32 mode)
994{
995 int rc;
996 struct qeth_cmd_buffer *iob;
997 struct qeth_ipa_cmd *cmd;
998
999 QETH_DBF_TEXT(trace, 4, "adpmode");
1000
1001 iob = qeth_get_adapter_cmd(card, command,
1002 sizeof(struct qeth_ipacmd_setadpparms));
1003 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1004 cmd->data.setadapterparms.data.mode = mode;
1005 rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb,
1006 NULL);
1007 return rc;
1008}
1009
1010static int qeth_l3_setadapter_hstr(struct qeth_card *card)
1011{
1012 int rc;
1013
1014 QETH_DBF_TEXT(trace, 4, "adphstr");
1015
1016 if (qeth_adp_supported(card, IPA_SETADP_SET_BROADCAST_MODE)) {
1017 rc = qeth_l3_send_setadp_mode(card,
1018 IPA_SETADP_SET_BROADCAST_MODE,
1019 card->options.broadcast_mode);
1020 if (rc)
1021 PRINT_WARN("couldn't set broadcast mode on "
1022 "device %s: x%x\n",
1023 CARD_BUS_ID(card), rc);
1024 rc = qeth_l3_send_setadp_mode(card,
1025 IPA_SETADP_ALTER_MAC_ADDRESS,
1026 card->options.macaddr_mode);
1027 if (rc)
1028 PRINT_WARN("couldn't set macaddr mode on "
1029 "device %s: x%x\n", CARD_BUS_ID(card), rc);
1030 return rc;
1031 }
1032 if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL)
1033 PRINT_WARN("set adapter parameters not available "
1034 "to set broadcast mode, using ALLRINGS "
1035 "on device %s:\n", CARD_BUS_ID(card));
1036 if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL)
1037 PRINT_WARN("set adapter parameters not available "
1038 "to set macaddr mode, using NONCANONICAL "
1039 "on device %s:\n", CARD_BUS_ID(card));
1040 return 0;
1041}
1042
1043static int qeth_l3_setadapter_parms(struct qeth_card *card)
1044{
1045 int rc;
1046
1047 QETH_DBF_TEXT(setup, 2, "setadprm");
1048
1049 if (!qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
1050 PRINT_WARN("set adapter parameters not supported "
1051 "on device %s.\n",
1052 CARD_BUS_ID(card));
1053 QETH_DBF_TEXT(setup, 2, " notsupp");
1054 return 0;
1055 }
1056 rc = qeth_query_setadapterparms(card);
1057 if (rc) {
1058 PRINT_WARN("couldn't set adapter parameters on device %s: "
1059 "x%x\n", CARD_BUS_ID(card), rc);
1060 return rc;
1061 }
1062 if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) {
1063 rc = qeth_setadpparms_change_macaddr(card);
1064 if (rc)
1065 PRINT_WARN("couldn't get MAC address on "
1066 "device %s: x%x\n",
1067 CARD_BUS_ID(card), rc);
1068 }
1069
1070 if ((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
1071 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))
1072 rc = qeth_l3_setadapter_hstr(card);
1073
1074 return rc;
1075}
1076
1077static int qeth_l3_default_setassparms_cb(struct qeth_card *card,
1078 struct qeth_reply *reply, unsigned long data)
1079{
1080 struct qeth_ipa_cmd *cmd;
1081
1082 QETH_DBF_TEXT(trace, 4, "defadpcb");
1083
1084 cmd = (struct qeth_ipa_cmd *) data;
1085 if (cmd->hdr.return_code == 0) {
1086 cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
1087 if (cmd->hdr.prot_version == QETH_PROT_IPV4)
1088 card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
1089 if (cmd->hdr.prot_version == QETH_PROT_IPV6)
1090 card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
1091 }
1092 if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM &&
1093 cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
1094 card->info.csum_mask = cmd->data.setassparms.data.flags_32bit;
1095 QETH_DBF_TEXT_(trace, 3, "csum:%d", card->info.csum_mask);
1096 }
1097 return 0;
1098}
1099
1100static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd(
1101 struct qeth_card *card, enum qeth_ipa_funcs ipa_func, __u16 cmd_code,
1102 __u16 len, enum qeth_prot_versions prot)
1103{
1104 struct qeth_cmd_buffer *iob;
1105 struct qeth_ipa_cmd *cmd;
1106
1107 QETH_DBF_TEXT(trace, 4, "getasscm");
1108 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot);
1109
1110 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1111 cmd->data.setassparms.hdr.assist_no = ipa_func;
1112 cmd->data.setassparms.hdr.length = 8 + len;
1113 cmd->data.setassparms.hdr.command_code = cmd_code;
1114 cmd->data.setassparms.hdr.return_code = 0;
1115 cmd->data.setassparms.hdr.seq_no = 0;
1116
1117 return iob;
1118}
1119
1120static int qeth_l3_send_setassparms(struct qeth_card *card,
1121 struct qeth_cmd_buffer *iob, __u16 len, long data,
1122 int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
1123 unsigned long),
1124 void *reply_param)
1125{
1126 int rc;
1127 struct qeth_ipa_cmd *cmd;
1128
1129 QETH_DBF_TEXT(trace, 4, "sendassp");
1130
1131 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1132 if (len <= sizeof(__u32))
1133 cmd->data.setassparms.data.flags_32bit = (__u32) data;
1134 else /* (len > sizeof(__u32)) */
1135 memcpy(&cmd->data.setassparms.data, (void *) data, len);
1136
1137 rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
1138 return rc;
1139}
1140
1141#ifdef CONFIG_QETH_IPV6
1142static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card,
1143 enum qeth_ipa_funcs ipa_func, __u16 cmd_code)
1144{
1145 int rc;
1146 struct qeth_cmd_buffer *iob;
1147
1148 QETH_DBF_TEXT(trace, 4, "simassp6");
1149 iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code,
1150 0, QETH_PROT_IPV6);
1151 rc = qeth_l3_send_setassparms(card, iob, 0, 0,
1152 qeth_l3_default_setassparms_cb, NULL);
1153 return rc;
1154}
1155#endif
1156
1157static int qeth_l3_send_simple_setassparms(struct qeth_card *card,
1158 enum qeth_ipa_funcs ipa_func, __u16 cmd_code, long data)
1159{
1160 int rc;
1161 int length = 0;
1162 struct qeth_cmd_buffer *iob;
1163
1164 QETH_DBF_TEXT(trace, 4, "simassp4");
1165 if (data)
1166 length = sizeof(__u32);
1167 iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code,
1168 length, QETH_PROT_IPV4);
1169 rc = qeth_l3_send_setassparms(card, iob, length, data,
1170 qeth_l3_default_setassparms_cb, NULL);
1171 return rc;
1172}
1173
1174static int qeth_l3_start_ipa_arp_processing(struct qeth_card *card)
1175{
1176 int rc;
1177
1178 QETH_DBF_TEXT(trace, 3, "ipaarp");
1179
1180 if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
1181 PRINT_WARN("ARP processing not supported "
1182 "on %s!\n", QETH_CARD_IFNAME(card));
1183 return 0;
1184 }
1185 rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING,
1186 IPA_CMD_ASS_START, 0);
1187 if (rc) {
1188 PRINT_WARN("Could not start ARP processing "
1189 "assist on %s: 0x%x\n",
1190 QETH_CARD_IFNAME(card), rc);
1191 }
1192 return rc;
1193}
1194
1195static int qeth_l3_start_ipa_ip_fragmentation(struct qeth_card *card)
1196{
1197 int rc;
1198
1199 QETH_DBF_TEXT(trace, 3, "ipaipfrg");
1200
1201 if (!qeth_is_supported(card, IPA_IP_FRAGMENTATION)) {
1202 PRINT_INFO("Hardware IP fragmentation not supported on %s\n",
1203 QETH_CARD_IFNAME(card));
1204 return -EOPNOTSUPP;
1205 }
1206
1207 rc = qeth_l3_send_simple_setassparms(card, IPA_IP_FRAGMENTATION,
1208 IPA_CMD_ASS_START, 0);
1209 if (rc) {
1210 PRINT_WARN("Could not start Hardware IP fragmentation "
1211 "assist on %s: 0x%x\n",
1212 QETH_CARD_IFNAME(card), rc);
1213 } else
1214 PRINT_INFO("Hardware IP fragmentation enabled \n");
1215 return rc;
1216}
1217
1218static int qeth_l3_start_ipa_source_mac(struct qeth_card *card)
1219{
1220 int rc;
1221
1222 QETH_DBF_TEXT(trace, 3, "stsrcmac");
1223
1224 if (!card->options.fake_ll)
1225 return -EOPNOTSUPP;
1226
1227 if (!qeth_is_supported(card, IPA_SOURCE_MAC)) {
1228 PRINT_INFO("Inbound source address not "
1229 "supported on %s\n", QETH_CARD_IFNAME(card));
1230 return -EOPNOTSUPP;
1231 }
1232
1233 rc = qeth_l3_send_simple_setassparms(card, IPA_SOURCE_MAC,
1234 IPA_CMD_ASS_START, 0);
1235 if (rc)
1236 PRINT_WARN("Could not start inbound source "
1237 "assist on %s: 0x%x\n",
1238 QETH_CARD_IFNAME(card), rc);
1239 return rc;
1240}
1241
1242static int qeth_l3_start_ipa_vlan(struct qeth_card *card)
1243{
1244 int rc = 0;
1245
1246 QETH_DBF_TEXT(trace, 3, "strtvlan");
1247
1248 if (!qeth_is_supported(card, IPA_FULL_VLAN)) {
1249 PRINT_WARN("VLAN not supported on %s\n",
1250 QETH_CARD_IFNAME(card));
1251 return -EOPNOTSUPP;
1252 }
1253
1254 rc = qeth_l3_send_simple_setassparms(card, IPA_VLAN_PRIO,
1255 IPA_CMD_ASS_START, 0);
1256 if (rc) {
1257 PRINT_WARN("Could not start vlan "
1258 "assist on %s: 0x%x\n",
1259 QETH_CARD_IFNAME(card), rc);
1260 } else {
1261 PRINT_INFO("VLAN enabled \n");
1262 }
1263 return rc;
1264}
1265
1266static int qeth_l3_start_ipa_multicast(struct qeth_card *card)
1267{
1268 int rc;
1269
1270 QETH_DBF_TEXT(trace, 3, "stmcast");
1271
1272 if (!qeth_is_supported(card, IPA_MULTICASTING)) {
1273 PRINT_WARN("Multicast not supported on %s\n",
1274 QETH_CARD_IFNAME(card));
1275 return -EOPNOTSUPP;
1276 }
1277
1278 rc = qeth_l3_send_simple_setassparms(card, IPA_MULTICASTING,
1279 IPA_CMD_ASS_START, 0);
1280 if (rc) {
1281 PRINT_WARN("Could not start multicast "
1282 "assist on %s: rc=%i\n",
1283 QETH_CARD_IFNAME(card), rc);
1284 } else {
1285 PRINT_INFO("Multicast enabled\n");
1286 card->dev->flags |= IFF_MULTICAST;
1287 }
1288 return rc;
1289}
1290
1291static int qeth_l3_query_ipassists_cb(struct qeth_card *card,
1292 struct qeth_reply *reply, unsigned long data)
1293{
1294 struct qeth_ipa_cmd *cmd;
1295
1296 QETH_DBF_TEXT(setup, 2, "qipasscb");
1297
1298 cmd = (struct qeth_ipa_cmd *) data;
1299 if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
1300 card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
1301 card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
1302 } else {
1303 card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
1304 card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
1305 }
1306 QETH_DBF_TEXT(setup, 2, "suppenbl");
1307 QETH_DBF_TEXT_(setup, 2, "%x", cmd->hdr.ipa_supported);
1308 QETH_DBF_TEXT_(setup, 2, "%x", cmd->hdr.ipa_enabled);
1309 return 0;
1310}
1311
1312static int qeth_l3_query_ipassists(struct qeth_card *card,
1313 enum qeth_prot_versions prot)
1314{
1315 int rc;
1316 struct qeth_cmd_buffer *iob;
1317
1318 QETH_DBF_TEXT_(setup, 2, "qipassi%i", prot);
1319 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
1320 rc = qeth_send_ipa_cmd(card, iob, qeth_l3_query_ipassists_cb, NULL);
1321 return rc;
1322}
1323
1324#ifdef CONFIG_QETH_IPV6
1325static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
1326{
1327 int rc;
1328
1329 QETH_DBF_TEXT(trace, 3, "softipv6");
1330
1331 if (card->info.type == QETH_CARD_TYPE_IQD)
1332 goto out;
1333
1334 rc = qeth_l3_query_ipassists(card, QETH_PROT_IPV6);
1335 if (rc) {
1336 PRINT_ERR("IPv6 query ipassist failed on %s\n",
1337 QETH_CARD_IFNAME(card));
1338 return rc;
1339 }
1340 rc = qeth_l3_send_simple_setassparms(card, IPA_IPV6,
1341 IPA_CMD_ASS_START, 3);
1342 if (rc) {
1343 PRINT_WARN("IPv6 start assist (version 4) failed "
1344 "on %s: 0x%x\n",
1345 QETH_CARD_IFNAME(card), rc);
1346 return rc;
1347 }
1348 rc = qeth_l3_send_simple_setassparms_ipv6(card, IPA_IPV6,
1349 IPA_CMD_ASS_START);
1350 if (rc) {
1351 PRINT_WARN("IPV6 start assist (version 6) failed "
1352 "on %s: 0x%x\n",
1353 QETH_CARD_IFNAME(card), rc);
1354 return rc;
1355 }
1356 rc = qeth_l3_send_simple_setassparms_ipv6(card, IPA_PASSTHRU,
1357 IPA_CMD_ASS_START);
1358 if (rc) {
1359 PRINT_WARN("Could not enable passthrough "
1360 "on %s: 0x%x\n",
1361 QETH_CARD_IFNAME(card), rc);
1362 return rc;
1363 }
1364out:
1365 PRINT_INFO("IPV6 enabled \n");
1366 return 0;
1367}
1368#endif
1369
1370static int qeth_l3_start_ipa_ipv6(struct qeth_card *card)
1371{
1372 int rc = 0;
1373
1374 QETH_DBF_TEXT(trace, 3, "strtipv6");
1375
1376 if (!qeth_is_supported(card, IPA_IPV6)) {
1377 PRINT_WARN("IPv6 not supported on %s\n",
1378 QETH_CARD_IFNAME(card));
1379 return 0;
1380 }
1381#ifdef CONFIG_QETH_IPV6
1382 rc = qeth_l3_softsetup_ipv6(card);
1383#endif
1384 return rc ;
1385}
1386
1387static int qeth_l3_start_ipa_broadcast(struct qeth_card *card)
1388{
1389 int rc;
1390
1391 QETH_DBF_TEXT(trace, 3, "stbrdcst");
1392 card->info.broadcast_capable = 0;
1393 if (!qeth_is_supported(card, IPA_FILTERING)) {
1394 PRINT_WARN("Broadcast not supported on %s\n",
1395 QETH_CARD_IFNAME(card));
1396 rc = -EOPNOTSUPP;
1397 goto out;
1398 }
1399 rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
1400 IPA_CMD_ASS_START, 0);
1401 if (rc) {
1402 PRINT_WARN("Could not enable broadcasting filtering "
1403 "on %s: 0x%x\n",
1404 QETH_CARD_IFNAME(card), rc);
1405 goto out;
1406 }
1407
1408 rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
1409 IPA_CMD_ASS_CONFIGURE, 1);
1410 if (rc) {
1411 PRINT_WARN("Could not set up broadcast filtering on %s: 0x%x\n",
1412 QETH_CARD_IFNAME(card), rc);
1413 goto out;
1414 }
1415 card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO;
1416 PRINT_INFO("Broadcast enabled \n");
1417 rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
1418 IPA_CMD_ASS_ENABLE, 1);
1419 if (rc) {
1420 PRINT_WARN("Could not set up broadcast echo filtering on "
1421 "%s: 0x%x\n", QETH_CARD_IFNAME(card), rc);
1422 goto out;
1423 }
1424 card->info.broadcast_capable = QETH_BROADCAST_WITHOUT_ECHO;
1425out:
1426 if (card->info.broadcast_capable)
1427 card->dev->flags |= IFF_BROADCAST;
1428 else
1429 card->dev->flags &= ~IFF_BROADCAST;
1430 return rc;
1431}
1432
1433static int qeth_l3_send_checksum_command(struct qeth_card *card)
1434{
1435 int rc;
1436
1437 rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
1438 IPA_CMD_ASS_START, 0);
1439 if (rc) {
1440 PRINT_WARN("Starting Inbound HW Checksumming failed on %s: "
1441 "0x%x,\ncontinuing using Inbound SW Checksumming\n",
1442 QETH_CARD_IFNAME(card), rc);
1443 return rc;
1444 }
1445 rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
1446 IPA_CMD_ASS_ENABLE,
1447 card->info.csum_mask);
1448 if (rc) {
1449 PRINT_WARN("Enabling Inbound HW Checksumming failed on %s: "
1450 "0x%x,\ncontinuing using Inbound SW Checksumming\n",
1451 QETH_CARD_IFNAME(card), rc);
1452 return rc;
1453 }
1454 return 0;
1455}
1456
1457static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
1458{
1459 int rc = 0;
1460
1461 QETH_DBF_TEXT(trace, 3, "strtcsum");
1462
1463 if (card->options.checksum_type == NO_CHECKSUMMING) {
1464 PRINT_WARN("Using no checksumming on %s.\n",
1465 QETH_CARD_IFNAME(card));
1466 return 0;
1467 }
1468 if (card->options.checksum_type == SW_CHECKSUMMING) {
1469 PRINT_WARN("Using SW checksumming on %s.\n",
1470 QETH_CARD_IFNAME(card));
1471 return 0;
1472 }
1473 if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
1474 PRINT_WARN("Inbound HW Checksumming not "
1475 "supported on %s,\ncontinuing "
1476 "using Inbound SW Checksumming\n",
1477 QETH_CARD_IFNAME(card));
1478 card->options.checksum_type = SW_CHECKSUMMING;
1479 return 0;
1480 }
1481 rc = qeth_l3_send_checksum_command(card);
1482 if (!rc)
1483 PRINT_INFO("HW Checksumming (inbound) enabled \n");
1484
1485 return rc;
1486}
1487
1488static int qeth_l3_start_ipa_tso(struct qeth_card *card)
1489{
1490 int rc;
1491
1492 QETH_DBF_TEXT(trace, 3, "sttso");
1493
1494 if (!qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
1495 PRINT_WARN("Outbound TSO not supported on %s\n",
1496 QETH_CARD_IFNAME(card));
1497 rc = -EOPNOTSUPP;
1498 } else {
1499 rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
1500 IPA_CMD_ASS_START, 0);
1501 if (rc)
1502 PRINT_WARN("Could not start outbound TSO "
1503 "assist on %s: rc=%i\n",
1504 QETH_CARD_IFNAME(card), rc);
1505 else
1506 PRINT_INFO("Outbound TSO enabled\n");
1507 }
1508 if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)) {
1509 card->options.large_send = QETH_LARGE_SEND_NO;
1510 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
1511 }
1512 return rc;
1513}
1514
1515static int qeth_l3_start_ipassists(struct qeth_card *card)
1516{
1517 QETH_DBF_TEXT(trace, 3, "strtipas");
1518 qeth_l3_start_ipa_arp_processing(card); /* go on*/
1519 qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/
1520 qeth_l3_start_ipa_source_mac(card); /* go on*/
1521 qeth_l3_start_ipa_vlan(card); /* go on*/
1522 qeth_l3_start_ipa_multicast(card); /* go on*/
1523 qeth_l3_start_ipa_ipv6(card); /* go on*/
1524 qeth_l3_start_ipa_broadcast(card); /* go on*/
1525 qeth_l3_start_ipa_checksum(card); /* go on*/
1526 qeth_l3_start_ipa_tso(card); /* go on*/
1527 return 0;
1528}
1529
1530static int qeth_l3_put_unique_id(struct qeth_card *card)
1531{
1532
1533 int rc = 0;
1534 struct qeth_cmd_buffer *iob;
1535 struct qeth_ipa_cmd *cmd;
1536
1537 QETH_DBF_TEXT(trace, 2, "puniqeid");
1538
1539 if ((card->info.unique_id & UNIQUE_ID_NOT_BY_CARD) ==
1540 UNIQUE_ID_NOT_BY_CARD)
1541 return -1;
1542 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_DESTROY_ADDR,
1543 QETH_PROT_IPV6);
1544 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1545 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
1546 card->info.unique_id;
1547 memcpy(&cmd->data.create_destroy_addr.unique_id[0],
1548 card->dev->dev_addr, OSA_ADDR_LEN);
1549 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
1550 return rc;
1551}
1552
1553static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card,
1554 struct qeth_reply *reply, unsigned long data)
1555{
1556 struct qeth_ipa_cmd *cmd;
1557
1558 cmd = (struct qeth_ipa_cmd *) data;
1559 if (cmd->hdr.return_code == 0)
1560 memcpy(card->dev->dev_addr,
1561 cmd->data.create_destroy_addr.unique_id, ETH_ALEN);
1562 else
1563 random_ether_addr(card->dev->dev_addr);
1564
1565 return 0;
1566}
1567
1568static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card)
1569{
1570 int rc = 0;
1571 struct qeth_cmd_buffer *iob;
1572 struct qeth_ipa_cmd *cmd;
1573
1574 QETH_DBF_TEXT(setup, 2, "hsrmac");
1575
1576 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR,
1577 QETH_PROT_IPV6);
1578 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1579 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
1580 card->info.unique_id;
1581
1582 rc = qeth_send_ipa_cmd(card, iob, qeth_l3_iqd_read_initial_mac_cb,
1583 NULL);
1584 return rc;
1585}
1586
1587static int qeth_l3_get_unique_id_cb(struct qeth_card *card,
1588 struct qeth_reply *reply, unsigned long data)
1589{
1590 struct qeth_ipa_cmd *cmd;
1591
1592 cmd = (struct qeth_ipa_cmd *) data;
1593 if (cmd->hdr.return_code == 0)
1594 card->info.unique_id = *((__u16 *)
1595 &cmd->data.create_destroy_addr.unique_id[6]);
1596 else {
1597 card->info.unique_id = UNIQUE_ID_IF_CREATE_ADDR_FAILED |
1598 UNIQUE_ID_NOT_BY_CARD;
1599 PRINT_WARN("couldn't get a unique id from the card on device "
1600 "%s (result=x%x), using default id. ipv6 "
1601 "autoconfig on other lpars may lead to duplicate "
1602 "ip addresses. please use manually "
1603 "configured ones.\n",
1604 CARD_BUS_ID(card), cmd->hdr.return_code);
1605 }
1606 return 0;
1607}
1608
1609static int qeth_l3_get_unique_id(struct qeth_card *card)
1610{
1611 int rc = 0;
1612 struct qeth_cmd_buffer *iob;
1613 struct qeth_ipa_cmd *cmd;
1614
1615 QETH_DBF_TEXT(setup, 2, "guniqeid");
1616
1617 if (!qeth_is_supported(card, IPA_IPV6)) {
1618 card->info.unique_id = UNIQUE_ID_IF_CREATE_ADDR_FAILED |
1619 UNIQUE_ID_NOT_BY_CARD;
1620 return 0;
1621 }
1622
1623 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR,
1624 QETH_PROT_IPV6);
1625 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1626 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
1627 card->info.unique_id;
1628
1629 rc = qeth_send_ipa_cmd(card, iob, qeth_l3_get_unique_id_cb, NULL);
1630 return rc;
1631}
1632
1633static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
1634 struct net_device *dev)
1635{
1636 if (dev->type == ARPHRD_IEEE802_TR)
1637 ip_tr_mc_map(ipm, mac);
1638 else
1639 ip_eth_mc_map(ipm, mac);
1640}
1641
1642static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev)
1643{
1644 struct qeth_ipaddr *ipm;
1645 struct ip_mc_list *im4;
1646 char buf[MAX_ADDR_LEN];
1647
1648 QETH_DBF_TEXT(trace, 4, "addmc");
1649 for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
1650 qeth_l3_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev);
1651 ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
1652 if (!ipm)
1653 continue;
1654 ipm->u.a4.addr = im4->multiaddr;
1655 memcpy(ipm->mac, buf, OSA_ADDR_LEN);
1656 ipm->is_multicast = 1;
1657 if (!qeth_l3_add_ip(card, ipm))
1658 kfree(ipm);
1659 }
1660}
1661
1662static void qeth_l3_add_vlan_mc(struct qeth_card *card)
1663{
1664 struct in_device *in_dev;
1665 struct vlan_group *vg;
1666 int i;
1667
1668 QETH_DBF_TEXT(trace, 4, "addmcvl");
1669 if (!qeth_is_supported(card, IPA_FULL_VLAN) || (card->vlangrp == NULL))
1670 return;
1671
1672 vg = card->vlangrp;
1673 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
1674 struct net_device *netdev = vlan_group_get_device(vg, i);
1675 if (netdev == NULL ||
1676 !(netdev->flags & IFF_UP))
1677 continue;
1678 in_dev = in_dev_get(netdev);
1679 if (!in_dev)
1680 continue;
1681 read_lock(&in_dev->mc_list_lock);
1682 qeth_l3_add_mc(card, in_dev);
1683 read_unlock(&in_dev->mc_list_lock);
1684 in_dev_put(in_dev);
1685 }
1686}
1687
1688static void qeth_l3_add_multicast_ipv4(struct qeth_card *card)
1689{
1690 struct in_device *in4_dev;
1691
1692 QETH_DBF_TEXT(trace, 4, "chkmcv4");
1693 in4_dev = in_dev_get(card->dev);
1694 if (in4_dev == NULL)
1695 return;
1696 read_lock(&in4_dev->mc_list_lock);
1697 qeth_l3_add_mc(card, in4_dev);
1698 qeth_l3_add_vlan_mc(card);
1699 read_unlock(&in4_dev->mc_list_lock);
1700 in_dev_put(in4_dev);
1701}
1702
1703#ifdef CONFIG_QETH_IPV6
1704static void qeth_l3_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
1705{
1706 struct qeth_ipaddr *ipm;
1707 struct ifmcaddr6 *im6;
1708 char buf[MAX_ADDR_LEN];
1709
1710 QETH_DBF_TEXT(trace, 4, "addmc6");
1711 for (im6 = in6_dev->mc_list; im6 != NULL; im6 = im6->next) {
1712 ndisc_mc_map(&im6->mca_addr, buf, in6_dev->dev, 0);
1713 ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
1714 if (!ipm)
1715 continue;
1716 ipm->is_multicast = 1;
1717 memcpy(ipm->mac, buf, OSA_ADDR_LEN);
1718 memcpy(&ipm->u.a6.addr, &im6->mca_addr.s6_addr,
1719 sizeof(struct in6_addr));
1720 if (!qeth_l3_add_ip(card, ipm))
1721 kfree(ipm);
1722 }
1723}
1724
1725static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
1726{
1727 struct inet6_dev *in_dev;
1728 struct vlan_group *vg;
1729 int i;
1730
1731 QETH_DBF_TEXT(trace, 4, "admc6vl");
1732 if (!qeth_is_supported(card, IPA_FULL_VLAN) || (card->vlangrp == NULL))
1733 return;
1734
1735 vg = card->vlangrp;
1736 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
1737 struct net_device *netdev = vlan_group_get_device(vg, i);
1738 if (netdev == NULL ||
1739 !(netdev->flags & IFF_UP))
1740 continue;
1741 in_dev = in6_dev_get(netdev);
1742 if (!in_dev)
1743 continue;
1744 read_lock_bh(&in_dev->lock);
1745 qeth_l3_add_mc6(card, in_dev);
1746 read_unlock_bh(&in_dev->lock);
1747 in6_dev_put(in_dev);
1748 }
1749}
1750
1751static void qeth_l3_add_multicast_ipv6(struct qeth_card *card)
1752{
1753 struct inet6_dev *in6_dev;
1754
1755 QETH_DBF_TEXT(trace, 4, "chkmcv6");
1756 if (!qeth_is_supported(card, IPA_IPV6))
1757 return ;
1758 in6_dev = in6_dev_get(card->dev);
1759 if (in6_dev == NULL)
1760 return;
1761 read_lock_bh(&in6_dev->lock);
1762 qeth_l3_add_mc6(card, in6_dev);
1763 qeth_l3_add_vlan_mc6(card);
1764 read_unlock_bh(&in6_dev->lock);
1765 in6_dev_put(in6_dev);
1766}
1767#endif /* CONFIG_QETH_IPV6 */
1768
1769static void qeth_l3_free_vlan_addresses4(struct qeth_card *card,
1770 unsigned short vid)
1771{
1772 struct in_device *in_dev;
1773 struct in_ifaddr *ifa;
1774 struct qeth_ipaddr *addr;
1775
1776 QETH_DBF_TEXT(trace, 4, "frvaddr4");
1777
1778 in_dev = in_dev_get(vlan_group_get_device(card->vlangrp, vid));
1779 if (!in_dev)
1780 return;
1781 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
1782 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
1783 if (addr) {
1784 addr->u.a4.addr = ifa->ifa_address;
1785 addr->u.a4.mask = ifa->ifa_mask;
1786 addr->type = QETH_IP_TYPE_NORMAL;
1787 if (!qeth_l3_delete_ip(card, addr))
1788 kfree(addr);
1789 }
1790 }
1791 in_dev_put(in_dev);
1792}
1793
1794static void qeth_l3_free_vlan_addresses6(struct qeth_card *card,
1795 unsigned short vid)
1796{
1797#ifdef CONFIG_QETH_IPV6
1798 struct inet6_dev *in6_dev;
1799 struct inet6_ifaddr *ifa;
1800 struct qeth_ipaddr *addr;
1801
1802 QETH_DBF_TEXT(trace, 4, "frvaddr6");
1803
1804 in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid));
1805 if (!in6_dev)
1806 return;
1807 for (ifa = in6_dev->addr_list; ifa; ifa = ifa->lst_next) {
1808 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
1809 if (addr) {
1810 memcpy(&addr->u.a6.addr, &ifa->addr,
1811 sizeof(struct in6_addr));
1812 addr->u.a6.pfxlen = ifa->prefix_len;
1813 addr->type = QETH_IP_TYPE_NORMAL;
1814 if (!qeth_l3_delete_ip(card, addr))
1815 kfree(addr);
1816 }
1817 }
1818 in6_dev_put(in6_dev);
1819#endif /* CONFIG_QETH_IPV6 */
1820}
1821
1822static void qeth_l3_free_vlan_addresses(struct qeth_card *card,
1823 unsigned short vid)
1824{
1825 if (!card->vlangrp)
1826 return;
1827 qeth_l3_free_vlan_addresses4(card, vid);
1828 qeth_l3_free_vlan_addresses6(card, vid);
1829}
1830
1831static void qeth_l3_vlan_rx_register(struct net_device *dev,
1832 struct vlan_group *grp)
1833{
1834 struct qeth_card *card = netdev_priv(dev);
1835 unsigned long flags;
1836
1837 QETH_DBF_TEXT(trace, 4, "vlanreg");
1838 spin_lock_irqsave(&card->vlanlock, flags);
1839 card->vlangrp = grp;
1840 spin_unlock_irqrestore(&card->vlanlock, flags);
1841}
1842
1843static void qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
1844{
1845 struct net_device *vlandev;
1846 struct qeth_card *card = (struct qeth_card *) dev->priv;
1847 struct in_device *in_dev;
1848
1849 if (card->info.type == QETH_CARD_TYPE_IQD)
1850 return;
1851
1852 vlandev = vlan_group_get_device(card->vlangrp, vid);
1853 vlandev->neigh_setup = qeth_l3_neigh_setup;
1854
1855 in_dev = in_dev_get(vlandev);
1856#ifdef CONFIG_SYSCTL
1857 neigh_sysctl_unregister(in_dev->arp_parms);
1858#endif
1859 neigh_parms_release(&arp_tbl, in_dev->arp_parms);
1860
1861 in_dev->arp_parms = neigh_parms_alloc(vlandev, &arp_tbl);
1862#ifdef CONFIG_SYSCTL
1863 neigh_sysctl_register(vlandev, in_dev->arp_parms, NET_IPV4,
1864 NET_IPV4_NEIGH, "ipv4", NULL, NULL);
1865#endif
1866 in_dev_put(in_dev);
1867 return;
1868}
1869
1870static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
1871{
1872 struct qeth_card *card = netdev_priv(dev);
1873 unsigned long flags;
1874
1875 QETH_DBF_TEXT_(trace, 4, "kid:%d", vid);
1876 spin_lock_irqsave(&card->vlanlock, flags);
1877 /* unregister IP addresses of vlan device */
1878 qeth_l3_free_vlan_addresses(card, vid);
1879 vlan_group_set_device(card->vlangrp, vid, NULL);
1880 spin_unlock_irqrestore(&card->vlanlock, flags);
1881 qeth_l3_set_multicast_list(card->dev);
1882}
1883
1884static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
1885 struct sk_buff *skb, struct qeth_hdr *hdr)
1886{
1887 unsigned short vlan_id = 0;
1888 __be16 prot;
1889 struct iphdr *ip_hdr;
1890 unsigned char tg_addr[MAX_ADDR_LEN];
1891
1892 if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) {
1893 prot = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 :
1894 ETH_P_IP);
1895 switch (hdr->hdr.l3.flags & QETH_HDR_CAST_MASK) {
1896 case QETH_CAST_MULTICAST:
1897 switch (prot) {
1898#ifdef CONFIG_QETH_IPV6
1899 case __constant_htons(ETH_P_IPV6):
1900 ndisc_mc_map((struct in6_addr *)
1901 skb->data + 24,
1902 tg_addr, card->dev, 0);
1903 break;
1904#endif
1905 case __constant_htons(ETH_P_IP):
1906 ip_hdr = (struct iphdr *)skb->data;
1907 (card->dev->type == ARPHRD_IEEE802_TR) ?
1908 ip_tr_mc_map(ip_hdr->daddr, tg_addr):
1909 ip_eth_mc_map(ip_hdr->daddr, tg_addr);
1910 break;
1911 default:
1912 memcpy(tg_addr, card->dev->broadcast,
1913 card->dev->addr_len);
1914 }
1915 card->stats.multicast++;
1916 skb->pkt_type = PACKET_MULTICAST;
1917 break;
1918 case QETH_CAST_BROADCAST:
1919 memcpy(tg_addr, card->dev->broadcast,
1920 card->dev->addr_len);
1921 card->stats.multicast++;
1922 skb->pkt_type = PACKET_BROADCAST;
1923 break;
1924 case QETH_CAST_UNICAST:
1925 case QETH_CAST_ANYCAST:
1926 case QETH_CAST_NOCAST:
1927 default:
1928 skb->pkt_type = PACKET_HOST;
1929 memcpy(tg_addr, card->dev->dev_addr,
1930 card->dev->addr_len);
1931 }
1932 card->dev->header_ops->create(skb, card->dev, prot, tg_addr,
1933 "FAKELL", card->dev->addr_len);
1934 }
1935
1936#ifdef CONFIG_TR
1937 if (card->dev->type == ARPHRD_IEEE802_TR)
1938 skb->protocol = tr_type_trans(skb, card->dev);
1939 else
1940#endif
1941 skb->protocol = eth_type_trans(skb, card->dev);
1942
1943 if (hdr->hdr.l3.ext_flags &
1944 (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
1945 vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
1946 hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
1947 }
1948
1949 skb->ip_summed = card->options.checksum_type;
1950 if (card->options.checksum_type == HW_CHECKSUMMING) {
1951 if ((hdr->hdr.l3.ext_flags &
1952 (QETH_HDR_EXT_CSUM_HDR_REQ |
1953 QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
1954 (QETH_HDR_EXT_CSUM_HDR_REQ |
1955 QETH_HDR_EXT_CSUM_TRANSP_REQ))
1956 skb->ip_summed = CHECKSUM_UNNECESSARY;
1957 else
1958 skb->ip_summed = SW_CHECKSUMMING;
1959 }
1960
1961 return vlan_id;
1962}
1963
1964static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
1965 struct qeth_qdio_buffer *buf, int index)
1966{
1967 struct qdio_buffer_element *element;
1968 struct sk_buff *skb;
1969 struct qeth_hdr *hdr;
1970 int offset;
1971 __u16 vlan_tag = 0;
1972 unsigned int len;
1973
1974 /* get first element of current buffer */
1975 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
1976 offset = 0;
1977 if (card->options.performance_stats)
1978 card->perf_stats.bufs_rec++;
1979 while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
1980 &offset, &hdr))) {
1981 skb->dev = card->dev;
1982 /* is device UP ? */
1983 if (!(card->dev->flags & IFF_UP)) {
1984 dev_kfree_skb_any(skb);
1985 continue;
1986 }
1987
1988 switch (hdr->hdr.l3.id) {
1989 case QETH_HEADER_TYPE_LAYER3:
1990 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
1991 len = skb->len;
1992 if (vlan_tag)
1993 if (card->vlangrp)
1994 vlan_hwaccel_rx(skb, card->vlangrp,
1995 vlan_tag);
1996 else {
1997 dev_kfree_skb_any(skb);
1998 continue;
1999 }
2000 else
2001 netif_rx(skb);
2002 break;
2003 default:
2004 dev_kfree_skb_any(skb);
2005 QETH_DBF_TEXT(trace, 3, "inbunkno");
2006 QETH_DBF_HEX(control, 3, hdr, QETH_DBF_CONTROL_LEN);
2007 continue;
2008 }
2009
2010 card->dev->last_rx = jiffies;
2011 card->stats.rx_packets++;
2012 card->stats.rx_bytes += len;
2013 }
2014}
2015
2016static int qeth_l3_verify_vlan_dev(struct net_device *dev,
2017 struct qeth_card *card)
2018{
2019 int rc = 0;
2020 struct vlan_group *vg;
2021 int i;
2022
2023 vg = card->vlangrp;
2024 if (!vg)
2025 return rc;
2026
2027 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
2028 if (vlan_group_get_device(vg, i) == dev) {
2029 rc = QETH_VLAN_CARD;
2030 break;
2031 }
2032 }
2033
2034 if (rc && !(netdev_priv(vlan_dev_info(dev)->real_dev) == (void *)card))
2035 return 0;
2036
2037 return rc;
2038}
2039
2040static int qeth_l3_verify_dev(struct net_device *dev)
2041{
2042 struct qeth_card *card;
2043 unsigned long flags;
2044 int rc = 0;
2045
2046 read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
2047 list_for_each_entry(card, &qeth_core_card_list.list, list) {
2048 if (card->dev == dev) {
2049 rc = QETH_REAL_CARD;
2050 break;
2051 }
2052 rc = qeth_l3_verify_vlan_dev(dev, card);
2053 if (rc)
2054 break;
2055 }
2056 read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
2057
2058 return rc;
2059}
2060
2061static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
2062{
2063 struct qeth_card *card = NULL;
2064 int rc;
2065
2066 rc = qeth_l3_verify_dev(dev);
2067 if (rc == QETH_REAL_CARD)
2068 card = netdev_priv(dev);
2069 else if (rc == QETH_VLAN_CARD)
2070 card = netdev_priv(vlan_dev_info(dev)->real_dev);
2071 if (card->options.layer2)
2072 card = NULL;
2073 QETH_DBF_TEXT_(trace, 4, "%d", rc);
2074 return card ;
2075}
2076
2077static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
2078{
2079 int rc = 0;
2080
2081 QETH_DBF_TEXT(setup, 2, "stopcard");
2082 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
2083
2084 qeth_set_allowed_threads(card, 0, 1);
2085 if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD))
2086 return -ERESTARTSYS;
2087 if (card->read.state == CH_STATE_UP &&
2088 card->write.state == CH_STATE_UP &&
2089 (card->state == CARD_STATE_UP)) {
2090 if (recovery_mode)
2091 qeth_l3_stop(card->dev);
2092 if (!card->use_hard_stop) {
2093 rc = qeth_send_stoplan(card);
2094 if (rc)
2095 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
2096 }
2097 card->state = CARD_STATE_SOFTSETUP;
2098 }
2099 if (card->state == CARD_STATE_SOFTSETUP) {
2100 qeth_l3_clear_ip_list(card, !card->use_hard_stop, 1);
2101 qeth_clear_ipacmd_list(card);
2102 card->state = CARD_STATE_HARDSETUP;
2103 }
2104 if (card->state == CARD_STATE_HARDSETUP) {
2105 if (!card->use_hard_stop &&
2106 (card->info.type != QETH_CARD_TYPE_IQD)) {
2107 rc = qeth_l3_put_unique_id(card);
2108 if (rc)
2109 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
2110 }
2111 qeth_qdio_clear_card(card, 0);
2112 qeth_clear_qdio_buffers(card);
2113 qeth_clear_working_pool_list(card);
2114 card->state = CARD_STATE_DOWN;
2115 }
2116 if (card->state == CARD_STATE_DOWN) {
2117 qeth_clear_cmd_buffers(&card->read);
2118 qeth_clear_cmd_buffers(&card->write);
2119 }
2120 card->use_hard_stop = 0;
2121 return rc;
2122}
2123
2124static void qeth_l3_set_multicast_list(struct net_device *dev)
2125{
2126 struct qeth_card *card = netdev_priv(dev);
2127
2128 QETH_DBF_TEXT(trace, 3, "setmulti");
2129 qeth_l3_delete_mc_addresses(card);
2130 qeth_l3_add_multicast_ipv4(card);
2131#ifdef CONFIG_QETH_IPV6
2132 qeth_l3_add_multicast_ipv6(card);
2133#endif
2134 qeth_l3_set_ip_addr_list(card);
2135 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
2136 return;
2137 qeth_setadp_promisc_mode(card);
2138}
2139
2140static const char *qeth_l3_arp_get_error_cause(int *rc)
2141{
2142 switch (*rc) {
2143 case QETH_IPA_ARP_RC_FAILED:
2144 *rc = -EIO;
2145 return "operation failed";
2146 case QETH_IPA_ARP_RC_NOTSUPP:
2147 *rc = -EOPNOTSUPP;
2148 return "operation not supported";
2149 case QETH_IPA_ARP_RC_OUT_OF_RANGE:
2150 *rc = -EINVAL;
2151 return "argument out of range";
2152 case QETH_IPA_ARP_RC_Q_NOTSUPP:
2153 *rc = -EOPNOTSUPP;
2154 return "query operation not supported";
2155 case QETH_IPA_ARP_RC_Q_NO_DATA:
2156 *rc = -ENOENT;
2157 return "no query data available";
2158 default:
2159 return "unknown error";
2160 }
2161}
2162
2163static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries)
2164{
2165 int tmp;
2166 int rc;
2167
2168 QETH_DBF_TEXT(trace, 3, "arpstnoe");
2169
2170 /*
2171 * currently GuestLAN only supports the ARP assist function
2172 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES;
2173 * thus we say EOPNOTSUPP for this ARP function
2174 */
2175 if (card->info.guestlan)
2176 return -EOPNOTSUPP;
2177 if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
2178 PRINT_WARN("ARP processing not supported "
2179 "on %s!\n", QETH_CARD_IFNAME(card));
2180 return -EOPNOTSUPP;
2181 }
2182 rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING,
2183 IPA_CMD_ASS_ARP_SET_NO_ENTRIES,
2184 no_entries);
2185 if (rc) {
2186 tmp = rc;
2187 PRINT_WARN("Could not set number of ARP entries on %s: "
2188 "%s (0x%x/%d)\n", QETH_CARD_IFNAME(card),
2189 qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
2190 }
2191 return rc;
2192}
2193
2194static void qeth_l3_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo,
2195 struct qeth_arp_query_data *qdata, int entry_size,
2196 int uentry_size)
2197{
2198 char *entry_ptr;
2199 char *uentry_ptr;
2200 int i;
2201
2202 entry_ptr = (char *)&qdata->data;
2203 uentry_ptr = (char *)(qinfo->udata + qinfo->udata_offset);
2204 for (i = 0; i < qdata->no_entries; ++i) {
2205 /* strip off 32 bytes "media specific information" */
2206 memcpy(uentry_ptr, (entry_ptr + 32), entry_size - 32);
2207 entry_ptr += entry_size;
2208 uentry_ptr += uentry_size;
2209 }
2210}
2211
2212static int qeth_l3_arp_query_cb(struct qeth_card *card,
2213 struct qeth_reply *reply, unsigned long data)
2214{
2215 struct qeth_ipa_cmd *cmd;
2216 struct qeth_arp_query_data *qdata;
2217 struct qeth_arp_query_info *qinfo;
2218 int entry_size;
2219 int uentry_size;
2220 int i;
2221
2222 QETH_DBF_TEXT(trace, 4, "arpquecb");
2223
2224 qinfo = (struct qeth_arp_query_info *) reply->param;
2225 cmd = (struct qeth_ipa_cmd *) data;
2226 if (cmd->hdr.return_code) {
2227 QETH_DBF_TEXT_(trace, 4, "qaer1%i", cmd->hdr.return_code);
2228 return 0;
2229 }
2230 if (cmd->data.setassparms.hdr.return_code) {
2231 cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
2232 QETH_DBF_TEXT_(trace, 4, "qaer2%i", cmd->hdr.return_code);
2233 return 0;
2234 }
2235 qdata = &cmd->data.setassparms.data.query_arp;
2236 switch (qdata->reply_bits) {
2237 case 5:
2238 uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry5);
2239 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
2240 uentry_size = sizeof(struct qeth_arp_qi_entry5_short);
2241 break;
2242 case 7:
2243 /* fall through to default */
2244 default:
2245 /* tr is the same as eth -> entry7 */
2246 uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry7);
2247 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
2248 uentry_size = sizeof(struct qeth_arp_qi_entry7_short);
2249 break;
2250 }
2251 /* check if there is enough room in userspace */
2252 if ((qinfo->udata_len - qinfo->udata_offset) <
2253 qdata->no_entries * uentry_size){
2254 QETH_DBF_TEXT_(trace, 4, "qaer3%i", -ENOMEM);
2255 cmd->hdr.return_code = -ENOMEM;
2256 PRINT_WARN("query ARP user space buffer is too small for "
2257 "the returned number of ARP entries. "
2258 "Aborting query!\n");
2259 goto out_error;
2260 }
2261 QETH_DBF_TEXT_(trace, 4, "anore%i",
2262 cmd->data.setassparms.hdr.number_of_replies);
2263 QETH_DBF_TEXT_(trace, 4, "aseqn%i", cmd->data.setassparms.hdr.seq_no);
2264 QETH_DBF_TEXT_(trace, 4, "anoen%i", qdata->no_entries);
2265
2266 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) {
2267 /* strip off "media specific information" */
2268 qeth_l3_copy_arp_entries_stripped(qinfo, qdata, entry_size,
2269 uentry_size);
2270 } else
2271 /*copy entries to user buffer*/
2272 memcpy(qinfo->udata + qinfo->udata_offset,
2273 (char *)&qdata->data, qdata->no_entries*uentry_size);
2274
2275 qinfo->no_entries += qdata->no_entries;
2276 qinfo->udata_offset += (qdata->no_entries*uentry_size);
2277 /* check if all replies received ... */
2278 if (cmd->data.setassparms.hdr.seq_no <
2279 cmd->data.setassparms.hdr.number_of_replies)
2280 return 1;
2281 memcpy(qinfo->udata, &qinfo->no_entries, 4);
2282 /* keep STRIP_ENTRIES flag so the user program can distinguish
2283 * stripped entries from normal ones */
2284 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
2285 qdata->reply_bits |= QETH_QARP_STRIP_ENTRIES;
2286 memcpy(qinfo->udata + QETH_QARP_MASK_OFFSET, &qdata->reply_bits, 2);
2287 return 0;
2288out_error:
2289 i = 0;
2290 memcpy(qinfo->udata, &i, 4);
2291 return 0;
2292}
2293
2294static int qeth_l3_send_ipa_arp_cmd(struct qeth_card *card,
2295 struct qeth_cmd_buffer *iob, int len,
2296 int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
2297 unsigned long),
2298 void *reply_param)
2299{
2300 QETH_DBF_TEXT(trace, 4, "sendarp");
2301
2302 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
2303 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
2304 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
2305 return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
2306 reply_cb, reply_param);
2307}
2308
2309static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata)
2310{
2311 struct qeth_cmd_buffer *iob;
2312 struct qeth_arp_query_info qinfo = {0, };
2313 int tmp;
2314 int rc;
2315
2316 QETH_DBF_TEXT(trace, 3, "arpquery");
2317
2318 if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
2319 IPA_ARP_PROCESSING)) {
2320 PRINT_WARN("ARP processing not supported "
2321 "on %s!\n", QETH_CARD_IFNAME(card));
2322 return -EOPNOTSUPP;
2323 }
2324 /* get size of userspace buffer and mask_bits -> 6 bytes */
2325 if (copy_from_user(&qinfo, udata, 6))
2326 return -EFAULT;
2327 qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL);
2328 if (!qinfo.udata)
2329 return -ENOMEM;
2330 qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET;
2331 iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
2332 IPA_CMD_ASS_ARP_QUERY_INFO,
2333 sizeof(int), QETH_PROT_IPV4);
2334
2335 rc = qeth_l3_send_ipa_arp_cmd(card, iob,
2336 QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
2337 qeth_l3_arp_query_cb, (void *)&qinfo);
2338 if (rc) {
2339 tmp = rc;
2340 PRINT_WARN("Error while querying ARP cache on %s: %s "
2341 "(0x%x/%d)\n", QETH_CARD_IFNAME(card),
2342 qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
2343 if (copy_to_user(udata, qinfo.udata, 4))
2344 rc = -EFAULT;
2345 } else {
2346 if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
2347 rc = -EFAULT;
2348 }
2349 kfree(qinfo.udata);
2350 return rc;
2351}
2352
2353static int qeth_l3_arp_add_entry(struct qeth_card *card,
2354 struct qeth_arp_cache_entry *entry)
2355{
2356 struct qeth_cmd_buffer *iob;
2357 char buf[16];
2358 int tmp;
2359 int rc;
2360
2361 QETH_DBF_TEXT(trace, 3, "arpadent");
2362
2363 /*
2364 * currently GuestLAN only supports the ARP assist function
2365 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY;
2366 * thus we say EOPNOTSUPP for this ARP function
2367 */
2368 if (card->info.guestlan)
2369 return -EOPNOTSUPP;
2370 if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
2371 PRINT_WARN("ARP processing not supported "
2372 "on %s!\n", QETH_CARD_IFNAME(card));
2373 return -EOPNOTSUPP;
2374 }
2375
2376 iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
2377 IPA_CMD_ASS_ARP_ADD_ENTRY,
2378 sizeof(struct qeth_arp_cache_entry),
2379 QETH_PROT_IPV4);
2380 rc = qeth_l3_send_setassparms(card, iob,
2381 sizeof(struct qeth_arp_cache_entry),
2382 (unsigned long) entry,
2383 qeth_l3_default_setassparms_cb, NULL);
2384 if (rc) {
2385 tmp = rc;
2386 qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
2387 PRINT_WARN("Could not add ARP entry for address %s on %s: "
2388 "%s (0x%x/%d)\n",
2389 buf, QETH_CARD_IFNAME(card),
2390 qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
2391 }
2392 return rc;
2393}
2394
2395static int qeth_l3_arp_remove_entry(struct qeth_card *card,
2396 struct qeth_arp_cache_entry *entry)
2397{
2398 struct qeth_cmd_buffer *iob;
2399 char buf[16] = {0, };
2400 int tmp;
2401 int rc;
2402
2403 QETH_DBF_TEXT(trace, 3, "arprment");
2404
2405 /*
2406 * currently GuestLAN only supports the ARP assist function
2407 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY;
2408 * thus we say EOPNOTSUPP for this ARP function
2409 */
2410 if (card->info.guestlan)
2411 return -EOPNOTSUPP;
2412 if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
2413 PRINT_WARN("ARP processing not supported "
2414 "on %s!\n", QETH_CARD_IFNAME(card));
2415 return -EOPNOTSUPP;
2416 }
2417 memcpy(buf, entry, 12);
2418 iob = qeth_l3_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
2419 IPA_CMD_ASS_ARP_REMOVE_ENTRY,
2420 12,
2421 QETH_PROT_IPV4);
2422 rc = qeth_l3_send_setassparms(card, iob,
2423 12, (unsigned long)buf,
2424 qeth_l3_default_setassparms_cb, NULL);
2425 if (rc) {
2426 tmp = rc;
2427 memset(buf, 0, 16);
2428 qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
2429 PRINT_WARN("Could not delete ARP entry for address %s on %s: "
2430 "%s (0x%x/%d)\n",
2431 buf, QETH_CARD_IFNAME(card),
2432 qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
2433 }
2434 return rc;
2435}
2436
2437static int qeth_l3_arp_flush_cache(struct qeth_card *card)
2438{
2439 int rc;
2440 int tmp;
2441
2442 QETH_DBF_TEXT(trace, 3, "arpflush");
2443
2444 /*
2445 * currently GuestLAN only supports the ARP assist function
2446 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE;
2447 * thus we say EOPNOTSUPP for this ARP function
2448 */
2449 if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD))
2450 return -EOPNOTSUPP;
2451 if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
2452 PRINT_WARN("ARP processing not supported "
2453 "on %s!\n", QETH_CARD_IFNAME(card));
2454 return -EOPNOTSUPP;
2455 }
2456 rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING,
2457 IPA_CMD_ASS_ARP_FLUSH_CACHE, 0);
2458 if (rc) {
2459 tmp = rc;
2460 PRINT_WARN("Could not flush ARP cache on %s: %s (0x%x/%d)\n",
2461 QETH_CARD_IFNAME(card),
2462 qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
2463 }
2464 return rc;
2465}
2466
2467static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2468{
2469 struct qeth_card *card = netdev_priv(dev);
2470 struct qeth_arp_cache_entry arp_entry;
2471 struct mii_ioctl_data *mii_data;
2472 int rc = 0;
2473
2474 if (!card)
2475 return -ENODEV;
2476
2477 if ((card->state != CARD_STATE_UP) &&
2478 (card->state != CARD_STATE_SOFTSETUP))
2479 return -ENODEV;
2480
2481 switch (cmd) {
2482 case SIOC_QETH_ARP_SET_NO_ENTRIES:
2483 if (!capable(CAP_NET_ADMIN)) {
2484 rc = -EPERM;
2485 break;
2486 }
2487 rc = qeth_l3_arp_set_no_entries(card, rq->ifr_ifru.ifru_ivalue);
2488 break;
2489 case SIOC_QETH_ARP_QUERY_INFO:
2490 if (!capable(CAP_NET_ADMIN)) {
2491 rc = -EPERM;
2492 break;
2493 }
2494 rc = qeth_l3_arp_query(card, rq->ifr_ifru.ifru_data);
2495 break;
2496 case SIOC_QETH_ARP_ADD_ENTRY:
2497 if (!capable(CAP_NET_ADMIN)) {
2498 rc = -EPERM;
2499 break;
2500 }
2501 if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
2502 sizeof(struct qeth_arp_cache_entry)))
2503 rc = -EFAULT;
2504 else
2505 rc = qeth_l3_arp_add_entry(card, &arp_entry);
2506 break;
2507 case SIOC_QETH_ARP_REMOVE_ENTRY:
2508 if (!capable(CAP_NET_ADMIN)) {
2509 rc = -EPERM;
2510 break;
2511 }
2512 if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
2513 sizeof(struct qeth_arp_cache_entry)))
2514 rc = -EFAULT;
2515 else
2516 rc = qeth_l3_arp_remove_entry(card, &arp_entry);
2517 break;
2518 case SIOC_QETH_ARP_FLUSH_CACHE:
2519 if (!capable(CAP_NET_ADMIN)) {
2520 rc = -EPERM;
2521 break;
2522 }
2523 rc = qeth_l3_arp_flush_cache(card);
2524 break;
2525 case SIOC_QETH_ADP_SET_SNMP_CONTROL:
2526 rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
2527 break;
2528 case SIOC_QETH_GET_CARD_TYPE:
2529 if ((card->info.type == QETH_CARD_TYPE_OSAE) &&
2530 !card->info.guestlan)
2531 return 1;
2532 return 0;
2533 break;
2534 case SIOCGMIIPHY:
2535 mii_data = if_mii(rq);
2536 mii_data->phy_id = 0;
2537 break;
2538 case SIOCGMIIREG:
2539 mii_data = if_mii(rq);
2540 if (mii_data->phy_id != 0)
2541 rc = -EINVAL;
2542 else
2543 mii_data->val_out = qeth_mdio_read(dev,
2544 mii_data->phy_id,
2545 mii_data->reg_num);
2546 break;
2547 default:
2548 rc = -EOPNOTSUPP;
2549 }
2550 if (rc)
2551 QETH_DBF_TEXT_(trace, 2, "ioce%d", rc);
2552 return rc;
2553}
2554
2555static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
2556 struct sk_buff *skb, int ipv, int cast_type)
2557{
2558 QETH_DBF_TEXT(trace, 6, "fillhdr");
2559
2560 memset(hdr, 0, sizeof(struct qeth_hdr));
2561 hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
2562 hdr->hdr.l3.ext_flags = 0;
2563
2564 /*
2565 * before we're going to overwrite this location with next hop ip.
2566 * v6 uses passthrough, v4 sets the tag in the QDIO header.
2567 */
2568 if (card->vlangrp && vlan_tx_tag_present(skb)) {
2569 hdr->hdr.l3.ext_flags = (ipv == 4) ?
2570 QETH_HDR_EXT_VLAN_FRAME :
2571 QETH_HDR_EXT_INCLUDE_VLAN_TAG;
2572 hdr->hdr.l3.vlan_id = vlan_tx_tag_get(skb);
2573 }
2574
2575 hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr);
2576 if (ipv == 4) {
2577 /* IPv4 */
2578 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type);
2579 memset(hdr->hdr.l3.dest_addr, 0, 12);
2580 if ((skb->dst) && (skb->dst->neighbour)) {
2581 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
2582 *((u32 *) skb->dst->neighbour->primary_key);
2583 } else {
2584 /* fill in destination address used in ip header */
2585 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
2586 ip_hdr(skb)->daddr;
2587 }
2588 } else if (ipv == 6) {
2589 /* IPv6 */
2590 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type);
2591 if (card->info.type == QETH_CARD_TYPE_IQD)
2592 hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU;
2593 if ((skb->dst) && (skb->dst->neighbour)) {
2594 memcpy(hdr->hdr.l3.dest_addr,
2595 skb->dst->neighbour->primary_key, 16);
2596 } else {
2597 /* fill in destination address used in ip header */
2598 memcpy(hdr->hdr.l3.dest_addr,
2599 &ipv6_hdr(skb)->daddr, 16);
2600 }
2601 } else {
2602 /* passthrough */
2603 if ((skb->dev->type == ARPHRD_IEEE802_TR) &&
2604 !memcmp(skb->data + sizeof(struct qeth_hdr) +
2605 sizeof(__u16), skb->dev->broadcast, 6)) {
2606 hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
2607 QETH_HDR_PASSTHRU;
2608 } else if (!memcmp(skb->data + sizeof(struct qeth_hdr),
2609 skb->dev->broadcast, 6)) {
2610 /* broadcast? */
2611 hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
2612 QETH_HDR_PASSTHRU;
2613 } else {
2614 hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ?
2615 QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU :
2616 QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;
2617 }
2618 }
2619}
2620
2621static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2622{
2623 int rc;
2624 u16 *tag;
2625 struct qeth_hdr *hdr = NULL;
2626 int elements_needed = 0;
2627 struct qeth_card *card = netdev_priv(dev);
2628 struct sk_buff *new_skb = NULL;
2629 int ipv = qeth_get_ip_version(skb);
2630 int cast_type = qeth_get_cast_type(card, skb);
2631 struct qeth_qdio_out_q *queue = card->qdio.out_qs
2632 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
2633 int tx_bytes = skb->len;
2634 enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
2635 struct qeth_eddp_context *ctx = NULL;
2636
2637 QETH_DBF_TEXT(trace, 6, "l3xmit");
2638
2639 if ((card->info.type == QETH_CARD_TYPE_IQD) &&
2640 (skb->protocol != htons(ETH_P_IPV6)) &&
2641 (skb->protocol != htons(ETH_P_IP)))
2642 goto tx_drop;
2643
2644 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
2645 card->stats.tx_carrier_errors++;
2646 goto tx_drop;
2647 }
2648
2649 if ((cast_type == RTN_BROADCAST) &&
2650 (card->info.broadcast_capable == 0))
2651 goto tx_drop;
2652
2653 if (card->options.performance_stats) {
2654 card->perf_stats.outbound_cnt++;
2655 card->perf_stats.outbound_start_time = qeth_get_micros();
2656 }
2657
2658 /* create a clone with writeable headroom */
2659 new_skb = skb_realloc_headroom(skb, sizeof(struct qeth_hdr_tso) +
2660 VLAN_HLEN);
2661 if (!new_skb)
2662 goto tx_drop;
2663
2664 if (card->info.type == QETH_CARD_TYPE_IQD) {
2665 skb_pull(new_skb, ETH_HLEN);
2666 } else {
2667 if (new_skb->protocol == htons(ETH_P_IP)) {
2668 if (card->dev->type == ARPHRD_IEEE802_TR)
2669 skb_pull(new_skb, TR_HLEN);
2670 else
2671 skb_pull(new_skb, ETH_HLEN);
2672 }
2673
2674 if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp &&
2675 vlan_tx_tag_present(new_skb)) {
2676 skb_push(new_skb, VLAN_HLEN);
2677 skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);
2678 skb_copy_to_linear_data_offset(new_skb, 4,
2679 new_skb->data + 8, 4);
2680 skb_copy_to_linear_data_offset(new_skb, 8,
2681 new_skb->data + 12, 4);
2682 tag = (u16 *)(new_skb->data + 12);
2683 *tag = __constant_htons(ETH_P_8021Q);
2684 *(tag + 1) = htons(vlan_tx_tag_get(new_skb));
2685 VLAN_TX_SKB_CB(new_skb)->magic = 0;
2686 }
2687 }
2688
2689 netif_stop_queue(dev);
2690
2691 if (skb_is_gso(new_skb))
2692 large_send = card->options.large_send;
2693
2694 /* fix hardware limitation: as long as we do not have sbal
2695 * chaining we can not send long frag lists so we temporary
2696 * switch to EDDP
2697 */
2698 if ((large_send == QETH_LARGE_SEND_TSO) &&
2699 ((skb_shinfo(new_skb)->nr_frags + 2) > 16))
2700 large_send = QETH_LARGE_SEND_EDDP;
2701
2702 if ((large_send == QETH_LARGE_SEND_TSO) &&
2703 (cast_type == RTN_UNSPEC)) {
2704 hdr = (struct qeth_hdr *)skb_push(new_skb,
2705 sizeof(struct qeth_hdr_tso));
2706 memset(hdr, 0, sizeof(struct qeth_hdr_tso));
2707 qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type);
2708 qeth_tso_fill_header(card, hdr, new_skb);
2709 elements_needed++;
2710 } else {
2711 hdr = (struct qeth_hdr *)skb_push(new_skb,
2712 sizeof(struct qeth_hdr));
2713 qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type);
2714 }
2715
2716 if (large_send == QETH_LARGE_SEND_EDDP) {
2717 /* new_skb is not owned by a socket so we use skb to get
2718 * the protocol
2719 */
2720 ctx = qeth_eddp_create_context(card, new_skb, hdr,
2721 skb->sk->sk_protocol);
2722 if (ctx == NULL) {
2723 PRINT_WARN("could not create eddp context\n");
2724 goto tx_drop;
2725 }
2726 } else {
2727 int elems = qeth_get_elements_no(card, (void *)hdr, new_skb,
2728 elements_needed);
2729 if (!elems)
2730 goto tx_drop;
2731 elements_needed += elems;
2732 }
2733
2734 if ((large_send == QETH_LARGE_SEND_NO) &&
2735 (new_skb->ip_summed == CHECKSUM_PARTIAL))
2736 qeth_tx_csum(new_skb);
2737
2738 if (card->info.type != QETH_CARD_TYPE_IQD)
2739 rc = qeth_do_send_packet(card, queue, new_skb, hdr,
2740 elements_needed, ctx);
2741 else
2742 rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
2743 elements_needed, ctx);
2744
2745 if (!rc) {
2746 card->stats.tx_packets++;
2747 card->stats.tx_bytes += tx_bytes;
2748 if (new_skb != skb)
2749 dev_kfree_skb_any(skb);
2750 if (card->options.performance_stats) {
2751 if (large_send != QETH_LARGE_SEND_NO) {
2752 card->perf_stats.large_send_bytes += tx_bytes;
2753 card->perf_stats.large_send_cnt++;
2754 }
2755 if (skb_shinfo(new_skb)->nr_frags > 0) {
2756 card->perf_stats.sg_skbs_sent++;
2757 /* nr_frags + skb->data */
2758 card->perf_stats.sg_frags_sent +=
2759 skb_shinfo(new_skb)->nr_frags + 1;
2760 }
2761 }
2762
2763 if (ctx != NULL) {
2764 qeth_eddp_put_context(ctx);
2765 dev_kfree_skb_any(new_skb);
2766 }
2767 } else {
2768 if (ctx != NULL)
2769 qeth_eddp_put_context(ctx);
2770
2771 if (rc == -EBUSY) {
2772 if (new_skb != skb)
2773 dev_kfree_skb_any(new_skb);
2774 return NETDEV_TX_BUSY;
2775 } else
2776 goto tx_drop;
2777 }
2778
2779 netif_wake_queue(dev);
2780 if (card->options.performance_stats)
2781 card->perf_stats.outbound_time += qeth_get_micros() -
2782 card->perf_stats.outbound_start_time;
2783 return rc;
2784
2785tx_drop:
2786 card->stats.tx_dropped++;
2787 card->stats.tx_errors++;
2788 if ((new_skb != skb) && new_skb)
2789 dev_kfree_skb_any(new_skb);
2790 dev_kfree_skb_any(skb);
2791 return NETDEV_TX_OK;
2792}
2793
2794static int qeth_l3_open(struct net_device *dev)
2795{
2796 struct qeth_card *card = netdev_priv(dev);
2797
2798 QETH_DBF_TEXT(trace, 4, "qethopen");
2799 if (card->state != CARD_STATE_SOFTSETUP)
2800 return -ENODEV;
2801 card->data.state = CH_STATE_UP;
2802 card->state = CARD_STATE_UP;
2803 card->dev->flags |= IFF_UP;
2804 netif_start_queue(dev);
2805
2806 if (!card->lan_online && netif_carrier_ok(dev))
2807 netif_carrier_off(dev);
2808 return 0;
2809}
2810
2811static int qeth_l3_stop(struct net_device *dev)
2812{
2813 struct qeth_card *card = netdev_priv(dev);
2814
2815 QETH_DBF_TEXT(trace, 4, "qethstop");
2816 netif_tx_disable(dev);
2817 card->dev->flags &= ~IFF_UP;
2818 if (card->state == CARD_STATE_UP)
2819 card->state = CARD_STATE_SOFTSETUP;
2820 return 0;
2821}
2822
2823static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev)
2824{
2825 struct qeth_card *card = netdev_priv(dev);
2826
2827 return (card->options.checksum_type == HW_CHECKSUMMING);
2828}
2829
2830static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data)
2831{
2832 struct qeth_card *card = netdev_priv(dev);
2833 enum qeth_card_states old_state;
2834 enum qeth_checksum_types csum_type;
2835
2836 if ((card->state != CARD_STATE_UP) &&
2837 (card->state != CARD_STATE_DOWN))
2838 return -EPERM;
2839
2840 if (data)
2841 csum_type = HW_CHECKSUMMING;
2842 else
2843 csum_type = SW_CHECKSUMMING;
2844
2845 if (card->options.checksum_type != csum_type) {
2846 old_state = card->state;
2847 if (card->state == CARD_STATE_UP)
2848 __qeth_l3_set_offline(card->gdev, 1);
2849 card->options.checksum_type = csum_type;
2850 if (old_state == CARD_STATE_UP)
2851 __qeth_l3_set_online(card->gdev, 1);
2852 }
2853 return 0;
2854}
2855
2856static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
2857{
2858 struct qeth_card *card = netdev_priv(dev);
2859
2860 if (data) {
2861 if (card->options.large_send == QETH_LARGE_SEND_NO) {
2862 if (card->info.type == QETH_CARD_TYPE_IQD)
2863 card->options.large_send = QETH_LARGE_SEND_EDDP;
2864 else
2865 card->options.large_send = QETH_LARGE_SEND_TSO;
2866 dev->features |= NETIF_F_TSO;
2867 }
2868 } else {
2869 dev->features &= ~NETIF_F_TSO;
2870 card->options.large_send = QETH_LARGE_SEND_NO;
2871 }
2872 return 0;
2873}
2874
2875static struct ethtool_ops qeth_l3_ethtool_ops = {
2876 .get_link = ethtool_op_get_link,
2877 .get_tx_csum = ethtool_op_get_tx_csum,
2878 .set_tx_csum = ethtool_op_set_tx_hw_csum,
2879 .get_rx_csum = qeth_l3_ethtool_get_rx_csum,
2880 .set_rx_csum = qeth_l3_ethtool_set_rx_csum,
2881 .get_sg = ethtool_op_get_sg,
2882 .set_sg = ethtool_op_set_sg,
2883 .get_tso = ethtool_op_get_tso,
2884 .set_tso = qeth_l3_ethtool_set_tso,
2885 .get_strings = qeth_core_get_strings,
2886 .get_ethtool_stats = qeth_core_get_ethtool_stats,
2887 .get_stats_count = qeth_core_get_stats_count,
2888 .get_drvinfo = qeth_core_get_drvinfo,
2889};
2890
2891/*
2892 * we need NOARP for IPv4 but we want neighbor solicitation for IPv6. Setting
2893 * NOARP on the netdevice is no option because it also turns off neighbor
2894 * solicitation. For IPv4 we install a neighbor_setup function. We don't want
2895 * arp resolution but we want the hard header (packet socket will work
2896 * e.g. tcpdump)
2897 */
2898static int qeth_l3_neigh_setup_noarp(struct neighbour *n)
2899{
2900 n->nud_state = NUD_NOARP;
2901 memcpy(n->ha, "FAKELL", 6);
2902 n->output = n->ops->connected_output;
2903 return 0;
2904}
2905
2906static int
2907qeth_l3_neigh_setup(struct net_device *dev, struct neigh_parms *np)
2908{
2909 if (np->tbl->family == AF_INET)
2910 np->neigh_setup = qeth_l3_neigh_setup_noarp;
2911
2912 return 0;
2913}
2914
2915static int qeth_l3_setup_netdev(struct qeth_card *card)
2916{
2917 if (card->info.type == QETH_CARD_TYPE_OSAE) {
2918 if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
2919 (card->info.link_type == QETH_LINK_TYPE_HSTR)) {
2920#ifdef CONFIG_TR
2921 card->dev = alloc_trdev(0);
2922#endif
2923 if (!card->dev)
2924 return -ENODEV;
2925 } else {
2926 card->dev = alloc_etherdev(0);
2927 if (!card->dev)
2928 return -ENODEV;
2929 card->dev->neigh_setup = qeth_l3_neigh_setup;
2930
2931 /*IPv6 address autoconfiguration stuff*/
2932 qeth_l3_get_unique_id(card);
2933 if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
2934 card->dev->dev_id = card->info.unique_id &
2935 0xffff;
2936 }
2937 } else if (card->info.type == QETH_CARD_TYPE_IQD) {
2938 card->dev = alloc_netdev(0, "hsi%d", ether_setup);
2939 if (!card->dev)
2940 return -ENODEV;
2941 card->dev->flags |= IFF_NOARP;
2942 qeth_l3_iqd_read_initial_mac(card);
2943 } else
2944 return -ENODEV;
2945
2946 card->dev->hard_start_xmit = qeth_l3_hard_start_xmit;
2947 card->dev->priv = card;
2948 card->dev->tx_timeout = &qeth_tx_timeout;
2949 card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
2950 card->dev->open = qeth_l3_open;
2951 card->dev->stop = qeth_l3_stop;
2952 card->dev->do_ioctl = qeth_l3_do_ioctl;
2953 card->dev->get_stats = qeth_get_stats;
2954 card->dev->change_mtu = qeth_change_mtu;
2955 card->dev->set_multicast_list = qeth_l3_set_multicast_list;
2956 card->dev->vlan_rx_register = qeth_l3_vlan_rx_register;
2957 card->dev->vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid;
2958 card->dev->vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid;
2959 card->dev->mtu = card->info.initial_mtu;
2960 SET_ETHTOOL_OPS(card->dev, &qeth_l3_ethtool_ops);
2961 card->dev->features |= NETIF_F_HW_VLAN_TX |
2962 NETIF_F_HW_VLAN_RX |
2963 NETIF_F_HW_VLAN_FILTER;
2964
2965 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
2966 return register_netdev(card->dev);
2967}
2968
2969static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
2970 unsigned int status, unsigned int qdio_err,
2971 unsigned int siga_err, unsigned int queue, int first_element,
2972 int count, unsigned long card_ptr)
2973{
2974 struct net_device *net_dev;
2975 struct qeth_card *card;
2976 struct qeth_qdio_buffer *buffer;
2977 int index;
2978 int i;
2979
2980 QETH_DBF_TEXT(trace, 6, "qdinput");
2981 card = (struct qeth_card *) card_ptr;
2982 net_dev = card->dev;
2983 if (card->options.performance_stats) {
2984 card->perf_stats.inbound_cnt++;
2985 card->perf_stats.inbound_start_time = qeth_get_micros();
2986 }
2987 if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
2988 if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
2989 QETH_DBF_TEXT(trace, 1, "qdinchk");
2990 QETH_DBF_TEXT_(trace, 1, "%s", CARD_BUS_ID(card));
2991 QETH_DBF_TEXT_(trace, 1, "%04X%04X",
2992 first_element, count);
2993 QETH_DBF_TEXT_(trace, 1, "%04X%04X", queue, status);
2994 qeth_schedule_recovery(card);
2995 return;
2996 }
2997 }
2998 for (i = first_element; i < (first_element + count); ++i) {
2999 index = i % QDIO_MAX_BUFFERS_PER_Q;
3000 buffer = &card->qdio.in_q->bufs[index];
3001 if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
3002 qeth_check_qdio_errors(buffer->buffer,
3003 qdio_err, siga_err, "qinerr")))
3004 qeth_l3_process_inbound_buffer(card, buffer, index);
3005 /* clear buffer and give back to hardware */
3006 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
3007 qeth_queue_input_buffer(card, index);
3008 }
3009 if (card->options.performance_stats)
3010 card->perf_stats.inbound_time += qeth_get_micros() -
3011 card->perf_stats.inbound_start_time;
3012}
3013
3014static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
3015{
3016 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3017
3018 qeth_l3_create_device_attributes(&gdev->dev);
3019 card->options.layer2 = 0;
3020 card->discipline.input_handler = (qdio_handler_t *)
3021 qeth_l3_qdio_input_handler;
3022 card->discipline.output_handler = (qdio_handler_t *)
3023 qeth_qdio_output_handler;
3024 card->discipline.recover = qeth_l3_recover;
3025 return 0;
3026}
3027
3028static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
3029{
3030 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
3031
3032 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
3033
3034 if (cgdev->state == CCWGROUP_ONLINE) {
3035 card->use_hard_stop = 1;
3036 qeth_l3_set_offline(cgdev);
3037 }
3038
3039 if (card->dev) {
3040 unregister_netdev(card->dev);
3041 card->dev = NULL;
3042 }
3043
3044 qeth_l3_remove_device_attributes(&cgdev->dev);
3045 qeth_l3_clear_ip_list(card, 0, 0);
3046 qeth_l3_clear_ipato_list(card);
3047 return;
3048}
3049
3050static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3051{
3052 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3053 int rc = 0;
3054 enum qeth_card_states recover_flag;
3055
3056 BUG_ON(!card);
3057 QETH_DBF_TEXT(setup, 2, "setonlin");
3058 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
3059
3060 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
3061 if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) {
3062 PRINT_WARN("set_online of card %s interrupted by user!\n",
3063 CARD_BUS_ID(card));
3064 return -ERESTARTSYS;
3065 }
3066
3067 recover_flag = card->state;
3068 rc = ccw_device_set_online(CARD_RDEV(card));
3069 if (rc) {
3070 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3071 return -EIO;
3072 }
3073 rc = ccw_device_set_online(CARD_WDEV(card));
3074 if (rc) {
3075 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3076 return -EIO;
3077 }
3078 rc = ccw_device_set_online(CARD_DDEV(card));
3079 if (rc) {
3080 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3081 return -EIO;
3082 }
3083
3084 rc = qeth_core_hardsetup_card(card);
3085 if (rc) {
3086 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
3087 goto out_remove;
3088 }
3089
3090 qeth_l3_query_ipassists(card, QETH_PROT_IPV4);
3091
3092 if (!card->dev && qeth_l3_setup_netdev(card))
3093 goto out_remove;
3094
3095 card->state = CARD_STATE_HARDSETUP;
3096 qeth_print_status_message(card);
3097
3098 /* softsetup */
3099 QETH_DBF_TEXT(setup, 2, "softsetp");
3100
3101 rc = qeth_send_startlan(card);
3102 if (rc) {
3103 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3104 if (rc == 0xe080) {
3105 PRINT_WARN("LAN on card %s if offline! "
3106 "Waiting for STARTLAN from card.\n",
3107 CARD_BUS_ID(card));
3108 card->lan_online = 0;
3109 }
3110 return rc;
3111 } else
3112 card->lan_online = 1;
3113 qeth_set_large_send(card, card->options.large_send);
3114
3115 rc = qeth_l3_setadapter_parms(card);
3116 if (rc)
3117 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
3118 rc = qeth_l3_start_ipassists(card);
3119 if (rc)
3120 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
3121 rc = qeth_l3_setrouting_v4(card);
3122 if (rc)
3123 QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
3124 rc = qeth_l3_setrouting_v6(card);
3125 if (rc)
3126 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
3127 netif_tx_disable(card->dev);
3128
3129 rc = qeth_init_qdio_queues(card);
3130 if (rc) {
3131 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
3132 goto out_remove;
3133 }
3134 card->state = CARD_STATE_SOFTSETUP;
3135 netif_carrier_on(card->dev);
3136
3137 qeth_set_allowed_threads(card, 0xffffffff, 0);
3138 if ((recover_flag == CARD_STATE_RECOVER) && recovery_mode) {
3139 qeth_l3_open(card->dev);
3140 qeth_l3_set_multicast_list(card->dev);
3141 }
3142 /* let user_space know that device is online */
3143 kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
3144 return 0;
3145out_remove:
3146 card->use_hard_stop = 1;
3147 qeth_l3_stop_card(card, 0);
3148 ccw_device_set_offline(CARD_DDEV(card));
3149 ccw_device_set_offline(CARD_WDEV(card));
3150 ccw_device_set_offline(CARD_RDEV(card));
3151 if (recover_flag == CARD_STATE_RECOVER)
3152 card->state = CARD_STATE_RECOVER;
3153 else
3154 card->state = CARD_STATE_DOWN;
3155 return -ENODEV;
3156}
3157
3158static int qeth_l3_set_online(struct ccwgroup_device *gdev)
3159{
3160 return __qeth_l3_set_online(gdev, 0);
3161}
3162
3163static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
3164 int recovery_mode)
3165{
3166 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
3167 int rc = 0, rc2 = 0, rc3 = 0;
3168 enum qeth_card_states recover_flag;
3169
3170 QETH_DBF_TEXT(setup, 3, "setoffl");
3171 QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
3172
3173 if (card->dev && netif_carrier_ok(card->dev))
3174 netif_carrier_off(card->dev);
3175 recover_flag = card->state;
3176 if (qeth_l3_stop_card(card, recovery_mode) == -ERESTARTSYS) {
3177 PRINT_WARN("Stopping card %s interrupted by user!\n",
3178 CARD_BUS_ID(card));
3179 return -ERESTARTSYS;
3180 }
3181 rc = ccw_device_set_offline(CARD_DDEV(card));
3182 rc2 = ccw_device_set_offline(CARD_WDEV(card));
3183 rc3 = ccw_device_set_offline(CARD_RDEV(card));
3184 if (!rc)
3185 rc = (rc2) ? rc2 : rc3;
3186 if (rc)
3187 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3188 if (recover_flag == CARD_STATE_UP)
3189 card->state = CARD_STATE_RECOVER;
3190 /* let user_space know that device is offline */
3191 kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
3192 return 0;
3193}
3194
3195static int qeth_l3_set_offline(struct ccwgroup_device *cgdev)
3196{
3197 return __qeth_l3_set_offline(cgdev, 0);
3198}
3199
3200static int qeth_l3_recover(void *ptr)
3201{
3202 struct qeth_card *card;
3203 int rc = 0;
3204
3205 card = (struct qeth_card *) ptr;
3206 QETH_DBF_TEXT(trace, 2, "recover1");
3207 QETH_DBF_HEX(trace, 2, &card, sizeof(void *));
3208 if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
3209 return 0;
3210 QETH_DBF_TEXT(trace, 2, "recover2");
3211 PRINT_WARN("Recovery of device %s started ...\n",
3212 CARD_BUS_ID(card));
3213 card->use_hard_stop = 1;
3214 __qeth_l3_set_offline(card->gdev, 1);
3215 rc = __qeth_l3_set_online(card->gdev, 1);
3216 /* don't run another scheduled recovery */
3217 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
3218 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
3219 if (!rc)
3220 PRINT_INFO("Device %s successfully recovered!\n",
3221 CARD_BUS_ID(card));
3222 else
3223 PRINT_INFO("Device %s could not be recovered!\n",
3224 CARD_BUS_ID(card));
3225 return 0;
3226}
3227
3228static void qeth_l3_shutdown(struct ccwgroup_device *gdev)
3229{
3230 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3231 qeth_l3_clear_ip_list(card, 0, 0);
3232 qeth_qdio_clear_card(card, 0);
3233 qeth_clear_qdio_buffers(card);
3234}
3235
3236struct ccwgroup_driver qeth_l3_ccwgroup_driver = {
3237 .probe = qeth_l3_probe_device,
3238 .remove = qeth_l3_remove_device,
3239 .set_online = qeth_l3_set_online,
3240 .set_offline = qeth_l3_set_offline,
3241 .shutdown = qeth_l3_shutdown,
3242};
3243EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver);
3244
3245static int qeth_l3_ip_event(struct notifier_block *this,
3246 unsigned long event, void *ptr)
3247{
3248 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
3249 struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev;
3250 struct qeth_ipaddr *addr;
3251 struct qeth_card *card;
3252
3253 if (dev->nd_net != &init_net)
3254 return NOTIFY_DONE;
3255
3256 QETH_DBF_TEXT(trace, 3, "ipevent");
3257 card = qeth_l3_get_card_from_dev(dev);
3258 if (!card)
3259 return NOTIFY_DONE;
3260
3261 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
3262 if (addr != NULL) {
3263 addr->u.a4.addr = ifa->ifa_address;
3264 addr->u.a4.mask = ifa->ifa_mask;
3265 addr->type = QETH_IP_TYPE_NORMAL;
3266 } else
3267 goto out;
3268
3269 switch (event) {
3270 case NETDEV_UP:
3271 if (!qeth_l3_add_ip(card, addr))
3272 kfree(addr);
3273 break;
3274 case NETDEV_DOWN:
3275 if (!qeth_l3_delete_ip(card, addr))
3276 kfree(addr);
3277 break;
3278 default:
3279 break;
3280 }
3281 qeth_l3_set_ip_addr_list(card);
3282out:
3283 return NOTIFY_DONE;
3284}
3285
3286static struct notifier_block qeth_l3_ip_notifier = {
3287 qeth_l3_ip_event,
3288 NULL,
3289};
3290
3291#ifdef CONFIG_QETH_IPV6
3292/**
3293 * IPv6 event handler
3294 */
3295static int qeth_l3_ip6_event(struct notifier_block *this,
3296 unsigned long event, void *ptr)
3297{
3298 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
3299 struct net_device *dev = (struct net_device *)ifa->idev->dev;
3300 struct qeth_ipaddr *addr;
3301 struct qeth_card *card;
3302
3303 QETH_DBF_TEXT(trace, 3, "ip6event");
3304
3305 card = qeth_l3_get_card_from_dev(dev);
3306 if (!card)
3307 return NOTIFY_DONE;
3308 if (!qeth_is_supported(card, IPA_IPV6))
3309 return NOTIFY_DONE;
3310
3311 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
3312 if (addr != NULL) {
3313 memcpy(&addr->u.a6.addr, &ifa->addr, sizeof(struct in6_addr));
3314 addr->u.a6.pfxlen = ifa->prefix_len;
3315 addr->type = QETH_IP_TYPE_NORMAL;
3316 } else
3317 goto out;
3318
3319 switch (event) {
3320 case NETDEV_UP:
3321 if (!qeth_l3_add_ip(card, addr))
3322 kfree(addr);
3323 break;
3324 case NETDEV_DOWN:
3325 if (!qeth_l3_delete_ip(card, addr))
3326 kfree(addr);
3327 break;
3328 default:
3329 break;
3330 }
3331 qeth_l3_set_ip_addr_list(card);
3332out:
3333 return NOTIFY_DONE;
3334}
3335
3336static struct notifier_block qeth_l3_ip6_notifier = {
3337 qeth_l3_ip6_event,
3338 NULL,
3339};
3340#endif
3341
3342static int qeth_l3_register_notifiers(void)
3343{
3344 int rc;
3345
3346 QETH_DBF_TEXT(trace, 5, "regnotif");
3347 rc = register_inetaddr_notifier(&qeth_l3_ip_notifier);
3348 if (rc)
3349 return rc;
3350#ifdef CONFIG_QETH_IPV6
3351 rc = register_inet6addr_notifier(&qeth_l3_ip6_notifier);
3352 if (rc) {
3353 unregister_inetaddr_notifier(&qeth_l3_ip_notifier);
3354 return rc;
3355 }
3356#else
3357 PRINT_WARN("layer 3 discipline no IPv6 support\n");
3358#endif
3359 return 0;
3360}
3361
3362static void qeth_l3_unregister_notifiers(void)
3363{
3364
3365 QETH_DBF_TEXT(trace, 5, "unregnot");
3366 BUG_ON(unregister_inetaddr_notifier(&qeth_l3_ip_notifier));
3367#ifdef CONFIG_QETH_IPV6
3368 BUG_ON(unregister_inet6addr_notifier(&qeth_l3_ip6_notifier));
3369#endif /* QETH_IPV6 */
3370}
3371
3372static int __init qeth_l3_init(void)
3373{
3374 int rc = 0;
3375
3376 PRINT_INFO("register layer 3 discipline\n");
3377 rc = qeth_l3_register_notifiers();
3378 return rc;
3379}
3380
3381static void __exit qeth_l3_exit(void)
3382{
3383 qeth_l3_unregister_notifiers();
3384 PRINT_INFO("unregister layer 3 discipline\n");
3385}
3386
3387module_init(qeth_l3_init);
3388module_exit(qeth_l3_exit);
3389MODULE_AUTHOR("Frank Blaschka <frank.blaschka@de.ibm.com>");
3390MODULE_DESCRIPTION("qeth layer 3 discipline");
3391MODULE_LICENSE("GPL");
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
new file mode 100644
index 000000000000..08f51fd902c4
--- /dev/null
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -0,0 +1,1051 @@
1/*
2 * drivers/s390/net/qeth_l3_sys.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
11#include "qeth_l3.h"
12
13#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
14struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
15
16static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
17{
18 if (card->options.checksum_type == SW_CHECKSUMMING)
19 return "sw";
20 else if (card->options.checksum_type == HW_CHECKSUMMING)
21 return "hw";
22 else
23 return "no";
24}
25
26static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
27 struct qeth_routing_info *route, char *buf)
28{
29 switch (route->type) {
30 case PRIMARY_ROUTER:
31 return sprintf(buf, "%s\n", "primary router");
32 case SECONDARY_ROUTER:
33 return sprintf(buf, "%s\n", "secondary router");
34 case MULTICAST_ROUTER:
35 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
36 return sprintf(buf, "%s\n", "multicast router+");
37 else
38 return sprintf(buf, "%s\n", "multicast router");
39 case PRIMARY_CONNECTOR:
40 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
41 return sprintf(buf, "%s\n", "primary connector+");
42 else
43 return sprintf(buf, "%s\n", "primary connector");
44 case SECONDARY_CONNECTOR:
45 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
46 return sprintf(buf, "%s\n", "secondary connector+");
47 else
48 return sprintf(buf, "%s\n", "secondary connector");
49 default:
50 return sprintf(buf, "%s\n", "no");
51 }
52}
53
54static ssize_t qeth_l3_dev_route4_show(struct device *dev,
55 struct device_attribute *attr, char *buf)
56{
57 struct qeth_card *card = dev_get_drvdata(dev);
58
59 if (!card)
60 return -EINVAL;
61
62 return qeth_l3_dev_route_show(card, &card->options.route4, buf);
63}
64
65static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
66 struct qeth_routing_info *route, enum qeth_prot_versions prot,
67 const char *buf, size_t count)
68{
69 enum qeth_routing_types old_route_type = route->type;
70 char *tmp;
71 int rc;
72
73 tmp = strsep((char **) &buf, "\n");
74
75 if (!strcmp(tmp, "no_router")) {
76 route->type = NO_ROUTER;
77 } else if (!strcmp(tmp, "primary_connector")) {
78 route->type = PRIMARY_CONNECTOR;
79 } else if (!strcmp(tmp, "secondary_connector")) {
80 route->type = SECONDARY_CONNECTOR;
81 } else if (!strcmp(tmp, "primary_router")) {
82 route->type = PRIMARY_ROUTER;
83 } else if (!strcmp(tmp, "secondary_router")) {
84 route->type = SECONDARY_ROUTER;
85 } else if (!strcmp(tmp, "multicast_router")) {
86 route->type = MULTICAST_ROUTER;
87 } else {
88 PRINT_WARN("Invalid routing type '%s'.\n", tmp);
89 return -EINVAL;
90 }
91 if (((card->state == CARD_STATE_SOFTSETUP) ||
92 (card->state == CARD_STATE_UP)) &&
93 (old_route_type != route->type)) {
94 if (prot == QETH_PROT_IPV4)
95 rc = qeth_l3_setrouting_v4(card);
96 else if (prot == QETH_PROT_IPV6)
97 rc = qeth_l3_setrouting_v6(card);
98 }
99 return count;
100}
101
102static ssize_t qeth_l3_dev_route4_store(struct device *dev,
103 struct device_attribute *attr, const char *buf, size_t count)
104{
105 struct qeth_card *card = dev_get_drvdata(dev);
106
107 if (!card)
108 return -EINVAL;
109
110 return qeth_l3_dev_route_store(card, &card->options.route4,
111 QETH_PROT_IPV4, buf, count);
112}
113
114static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
115 qeth_l3_dev_route4_store);
116
117static ssize_t qeth_l3_dev_route6_show(struct device *dev,
118 struct device_attribute *attr, char *buf)
119{
120 struct qeth_card *card = dev_get_drvdata(dev);
121
122 if (!card)
123 return -EINVAL;
124
125 if (!qeth_is_supported(card, IPA_IPV6))
126 return sprintf(buf, "%s\n", "n/a");
127
128 return qeth_l3_dev_route_show(card, &card->options.route6, buf);
129}
130
131static ssize_t qeth_l3_dev_route6_store(struct device *dev,
132 struct device_attribute *attr, const char *buf, size_t count)
133{
134 struct qeth_card *card = dev_get_drvdata(dev);
135
136 if (!card)
137 return -EINVAL;
138
139 if (!qeth_is_supported(card, IPA_IPV6)) {
140 PRINT_WARN("IPv6 not supported for interface %s.\n"
141 "Routing status no changed.\n",
142 QETH_CARD_IFNAME(card));
143 return -ENOTSUPP;
144 }
145
146 return qeth_l3_dev_route_store(card, &card->options.route6,
147 QETH_PROT_IPV6, buf, count);
148}
149
150static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
151 qeth_l3_dev_route6_store);
152
153static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
154 struct device_attribute *attr, char *buf)
155{
156 struct qeth_card *card = dev_get_drvdata(dev);
157
158 if (!card)
159 return -EINVAL;
160
161 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
162}
163
164static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
165 struct device_attribute *attr, const char *buf, size_t count)
166{
167 struct qeth_card *card = dev_get_drvdata(dev);
168 char *tmp;
169 int i;
170
171 if (!card)
172 return -EINVAL;
173
174 if ((card->state != CARD_STATE_DOWN) &&
175 (card->state != CARD_STATE_RECOVER))
176 return -EPERM;
177
178 i = simple_strtoul(buf, &tmp, 16);
179 if ((i == 0) || (i == 1))
180 card->options.fake_broadcast = i;
181 else {
182 PRINT_WARN("fake_broadcast: write 0 or 1 to this file!\n");
183 return -EINVAL;
184 }
185 return count;
186}
187
188static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
189 qeth_l3_dev_fake_broadcast_store);
190
191static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
192 struct device_attribute *attr, char *buf)
193{
194 struct qeth_card *card = dev_get_drvdata(dev);
195
196 if (!card)
197 return -EINVAL;
198
199 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
200 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
201 return sprintf(buf, "n/a\n");
202
203 return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
204 QETH_TR_BROADCAST_ALLRINGS)?
205 "all rings":"local");
206}
207
208static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
209 struct device_attribute *attr, const char *buf, size_t count)
210{
211 struct qeth_card *card = dev_get_drvdata(dev);
212 char *tmp;
213
214 if (!card)
215 return -EINVAL;
216
217 if ((card->state != CARD_STATE_DOWN) &&
218 (card->state != CARD_STATE_RECOVER))
219 return -EPERM;
220
221 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
222 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
223 PRINT_WARN("Device is not a tokenring device!\n");
224 return -EINVAL;
225 }
226
227 tmp = strsep((char **) &buf, "\n");
228
229 if (!strcmp(tmp, "local")) {
230 card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
231 return count;
232 } else if (!strcmp(tmp, "all_rings")) {
233 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
234 return count;
235 } else {
236 PRINT_WARN("broadcast_mode: invalid mode %s!\n",
237 tmp);
238 return -EINVAL;
239 }
240 return count;
241}
242
243static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
244 qeth_l3_dev_broadcast_mode_store);
245
246static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
247 struct device_attribute *attr, char *buf)
248{
249 struct qeth_card *card = dev_get_drvdata(dev);
250
251 if (!card)
252 return -EINVAL;
253
254 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
255 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
256 return sprintf(buf, "n/a\n");
257
258 return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
259 QETH_TR_MACADDR_CANONICAL)? 1:0);
260}
261
262static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
263 struct device_attribute *attr, const char *buf, size_t count)
264{
265 struct qeth_card *card = dev_get_drvdata(dev);
266 char *tmp;
267 int i;
268
269 if (!card)
270 return -EINVAL;
271
272 if ((card->state != CARD_STATE_DOWN) &&
273 (card->state != CARD_STATE_RECOVER))
274 return -EPERM;
275
276 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
277 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
278 PRINT_WARN("Device is not a tokenring device!\n");
279 return -EINVAL;
280 }
281
282 i = simple_strtoul(buf, &tmp, 16);
283 if ((i == 0) || (i == 1))
284 card->options.macaddr_mode = i?
285 QETH_TR_MACADDR_CANONICAL :
286 QETH_TR_MACADDR_NONCANONICAL;
287 else {
288 PRINT_WARN("canonical_macaddr: write 0 or 1 to this file!\n");
289 return -EINVAL;
290 }
291 return count;
292}
293
294static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
295 qeth_l3_dev_canonical_macaddr_store);
296
297static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
298 struct device_attribute *attr, char *buf)
299{
300 struct qeth_card *card = dev_get_drvdata(dev);
301
302 if (!card)
303 return -EINVAL;
304
305 return sprintf(buf, "%s checksumming\n",
306 qeth_l3_get_checksum_str(card));
307}
308
309static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
310 struct device_attribute *attr, const char *buf, size_t count)
311{
312 struct qeth_card *card = dev_get_drvdata(dev);
313 char *tmp;
314
315 if (!card)
316 return -EINVAL;
317
318 if ((card->state != CARD_STATE_DOWN) &&
319 (card->state != CARD_STATE_RECOVER))
320 return -EPERM;
321
322 tmp = strsep((char **) &buf, "\n");
323 if (!strcmp(tmp, "sw_checksumming"))
324 card->options.checksum_type = SW_CHECKSUMMING;
325 else if (!strcmp(tmp, "hw_checksumming"))
326 card->options.checksum_type = HW_CHECKSUMMING;
327 else if (!strcmp(tmp, "no_checksumming"))
328 card->options.checksum_type = NO_CHECKSUMMING;
329 else {
330 PRINT_WARN("Unknown checksumming type '%s'\n", tmp);
331 return -EINVAL;
332 }
333 return count;
334}
335
336static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
337 qeth_l3_dev_checksum_store);
338
339static struct attribute *qeth_l3_device_attrs[] = {
340 &dev_attr_route4.attr,
341 &dev_attr_route6.attr,
342 &dev_attr_fake_broadcast.attr,
343 &dev_attr_broadcast_mode.attr,
344 &dev_attr_canonical_macaddr.attr,
345 &dev_attr_checksumming.attr,
346 NULL,
347};
348
349static struct attribute_group qeth_l3_device_attr_group = {
350 .attrs = qeth_l3_device_attrs,
351};
352
353static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
354 struct device_attribute *attr, char *buf)
355{
356 struct qeth_card *card = dev_get_drvdata(dev);
357
358 if (!card)
359 return -EINVAL;
360
361 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
362}
363
364static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
365 struct device_attribute *attr, const char *buf, size_t count)
366{
367 struct qeth_card *card = dev_get_drvdata(dev);
368 char *tmp;
369
370 if (!card)
371 return -EINVAL;
372
373 if ((card->state != CARD_STATE_DOWN) &&
374 (card->state != CARD_STATE_RECOVER))
375 return -EPERM;
376
377 tmp = strsep((char **) &buf, "\n");
378 if (!strcmp(tmp, "toggle")) {
379 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
380 } else if (!strcmp(tmp, "1")) {
381 card->ipato.enabled = 1;
382 } else if (!strcmp(tmp, "0")) {
383 card->ipato.enabled = 0;
384 } else {
385 PRINT_WARN("ipato_enable: write 0, 1 or 'toggle' to "
386 "this file\n");
387 return -EINVAL;
388 }
389 return count;
390}
391
392static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
393 qeth_l3_dev_ipato_enable_show,
394 qeth_l3_dev_ipato_enable_store);
395
396static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
397 struct device_attribute *attr, char *buf)
398{
399 struct qeth_card *card = dev_get_drvdata(dev);
400
401 if (!card)
402 return -EINVAL;
403
404 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
405}
406
407static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
408 struct device_attribute *attr,
409 const char *buf, size_t count)
410{
411 struct qeth_card *card = dev_get_drvdata(dev);
412 char *tmp;
413
414 if (!card)
415 return -EINVAL;
416
417 tmp = strsep((char **) &buf, "\n");
418 if (!strcmp(tmp, "toggle")) {
419 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
420 } else if (!strcmp(tmp, "1")) {
421 card->ipato.invert4 = 1;
422 } else if (!strcmp(tmp, "0")) {
423 card->ipato.invert4 = 0;
424 } else {
425 PRINT_WARN("ipato_invert4: write 0, 1 or 'toggle' to "
426 "this file\n");
427 return -EINVAL;
428 }
429 return count;
430}
431
432static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
433 qeth_l3_dev_ipato_invert4_show,
434 qeth_l3_dev_ipato_invert4_store);
435
436static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
437 enum qeth_prot_versions proto)
438{
439 struct qeth_ipato_entry *ipatoe;
440 unsigned long flags;
441 char addr_str[40];
442 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
443 int i = 0;
444
445 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
446 /* add strlen for "/<mask>\n" */
447 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
448 spin_lock_irqsave(&card->ip_lock, flags);
449 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
450 if (ipatoe->proto != proto)
451 continue;
452 /* String must not be longer than PAGE_SIZE. So we check if
453 * string length gets near PAGE_SIZE. Then we can savely display
454 * the next IPv6 address (worst case, compared to IPv4) */
455 if ((PAGE_SIZE - i) <= entry_len)
456 break;
457 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
458 i += snprintf(buf + i, PAGE_SIZE - i,
459 "%s/%i\n", addr_str, ipatoe->mask_bits);
460 }
461 spin_unlock_irqrestore(&card->ip_lock, flags);
462 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
463
464 return i;
465}
466
467static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
468 struct device_attribute *attr, char *buf)
469{
470 struct qeth_card *card = dev_get_drvdata(dev);
471
472 if (!card)
473 return -EINVAL;
474
475 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
476}
477
478static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
479 u8 *addr, int *mask_bits)
480{
481 const char *start, *end;
482 char *tmp;
483 char buffer[40] = {0, };
484
485 start = buf;
486 /* get address string */
487 end = strchr(start, '/');
488 if (!end || (end - start >= 40)) {
489 PRINT_WARN("Invalid format for ipato_addx/delx. "
490 "Use <ip addr>/<mask bits>\n");
491 return -EINVAL;
492 }
493 strncpy(buffer, start, end - start);
494 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
495 PRINT_WARN("Invalid IP address format!\n");
496 return -EINVAL;
497 }
498 start = end + 1;
499 *mask_bits = simple_strtoul(start, &tmp, 10);
500 if (!strlen(start) ||
501 (tmp == start) ||
502 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
503 PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n");
504 return -EINVAL;
505 }
506 return 0;
507}
508
509static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
510 struct qeth_card *card, enum qeth_prot_versions proto)
511{
512 struct qeth_ipato_entry *ipatoe;
513 u8 addr[16];
514 int mask_bits;
515 int rc;
516
517 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
518 if (rc)
519 return rc;
520
521 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
522 if (!ipatoe) {
523 PRINT_WARN("No memory to allocate ipato entry\n");
524 return -ENOMEM;
525 }
526 ipatoe->proto = proto;
527 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
528 ipatoe->mask_bits = mask_bits;
529
530 rc = qeth_l3_add_ipato_entry(card, ipatoe);
531 if (rc) {
532 kfree(ipatoe);
533 return rc;
534 }
535
536 return count;
537}
538
539static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
540 struct device_attribute *attr, const char *buf, size_t count)
541{
542 struct qeth_card *card = dev_get_drvdata(dev);
543
544 if (!card)
545 return -EINVAL;
546
547 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
548}
549
550static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
551 qeth_l3_dev_ipato_add4_show,
552 qeth_l3_dev_ipato_add4_store);
553
554static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
555 struct qeth_card *card, enum qeth_prot_versions proto)
556{
557 u8 addr[16];
558 int mask_bits;
559 int rc;
560
561 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
562 if (rc)
563 return rc;
564
565 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
566
567 return count;
568}
569
570static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
571 struct device_attribute *attr, const char *buf, size_t count)
572{
573 struct qeth_card *card = dev_get_drvdata(dev);
574
575 if (!card)
576 return -EINVAL;
577
578 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
579}
580
581static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
582 qeth_l3_dev_ipato_del4_store);
583
584static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
585 struct device_attribute *attr, char *buf)
586{
587 struct qeth_card *card = dev_get_drvdata(dev);
588
589 if (!card)
590 return -EINVAL;
591
592 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
593}
594
595static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
596 struct device_attribute *attr, const char *buf, size_t count)
597{
598 struct qeth_card *card = dev_get_drvdata(dev);
599 char *tmp;
600
601 if (!card)
602 return -EINVAL;
603
604 tmp = strsep((char **) &buf, "\n");
605 if (!strcmp(tmp, "toggle")) {
606 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
607 } else if (!strcmp(tmp, "1")) {
608 card->ipato.invert6 = 1;
609 } else if (!strcmp(tmp, "0")) {
610 card->ipato.invert6 = 0;
611 } else {
612 PRINT_WARN("ipato_invert6: write 0, 1 or 'toggle' to "
613 "this file\n");
614 return -EINVAL;
615 }
616 return count;
617}
618
619static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
620 qeth_l3_dev_ipato_invert6_show,
621 qeth_l3_dev_ipato_invert6_store);
622
623
624static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
625 struct device_attribute *attr, char *buf)
626{
627 struct qeth_card *card = dev_get_drvdata(dev);
628
629 if (!card)
630 return -EINVAL;
631
632 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
633}
634
635static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
636 struct device_attribute *attr, const char *buf, size_t count)
637{
638 struct qeth_card *card = dev_get_drvdata(dev);
639
640 if (!card)
641 return -EINVAL;
642
643 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
644}
645
646static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
647 qeth_l3_dev_ipato_add6_show,
648 qeth_l3_dev_ipato_add6_store);
649
650static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
651 struct device_attribute *attr, const char *buf, size_t count)
652{
653 struct qeth_card *card = dev_get_drvdata(dev);
654
655 if (!card)
656 return -EINVAL;
657
658 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
659}
660
661static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
662 qeth_l3_dev_ipato_del6_store);
663
664static struct attribute *qeth_ipato_device_attrs[] = {
665 &dev_attr_ipato_enable.attr,
666 &dev_attr_ipato_invert4.attr,
667 &dev_attr_ipato_add4.attr,
668 &dev_attr_ipato_del4.attr,
669 &dev_attr_ipato_invert6.attr,
670 &dev_attr_ipato_add6.attr,
671 &dev_attr_ipato_del6.attr,
672 NULL,
673};
674
675static struct attribute_group qeth_device_ipato_group = {
676 .name = "ipa_takeover",
677 .attrs = qeth_ipato_device_attrs,
678};
679
680static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
681 enum qeth_prot_versions proto)
682{
683 struct qeth_ipaddr *ipaddr;
684 char addr_str[40];
685 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
686 unsigned long flags;
687 int i = 0;
688
689 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
690 entry_len += 2; /* \n + terminator */
691 spin_lock_irqsave(&card->ip_lock, flags);
692 list_for_each_entry(ipaddr, &card->ip_list, entry) {
693 if (ipaddr->proto != proto)
694 continue;
695 if (ipaddr->type != QETH_IP_TYPE_VIPA)
696 continue;
697 /* String must not be longer than PAGE_SIZE. So we check if
698 * string length gets near PAGE_SIZE. Then we can savely display
699 * the next IPv6 address (worst case, compared to IPv4) */
700 if ((PAGE_SIZE - i) <= entry_len)
701 break;
702 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
703 addr_str);
704 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
705 }
706 spin_unlock_irqrestore(&card->ip_lock, flags);
707 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
708
709 return i;
710}
711
712static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
713 struct device_attribute *attr, char *buf)
714{
715 struct qeth_card *card = dev_get_drvdata(dev);
716
717 if (!card)
718 return -EINVAL;
719
720 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
721}
722
723static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
724 u8 *addr)
725{
726 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
727 PRINT_WARN("Invalid IP address format!\n");
728 return -EINVAL;
729 }
730 return 0;
731}
732
733static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
734 struct qeth_card *card, enum qeth_prot_versions proto)
735{
736 u8 addr[16] = {0, };
737 int rc;
738
739 rc = qeth_l3_parse_vipae(buf, proto, addr);
740 if (rc)
741 return rc;
742
743 rc = qeth_l3_add_vipa(card, proto, addr);
744 if (rc)
745 return rc;
746
747 return count;
748}
749
750static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
751 struct device_attribute *attr, const char *buf, size_t count)
752{
753 struct qeth_card *card = dev_get_drvdata(dev);
754
755 if (!card)
756 return -EINVAL;
757
758 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
759}
760
761static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
762 qeth_l3_dev_vipa_add4_show,
763 qeth_l3_dev_vipa_add4_store);
764
765static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
766 struct qeth_card *card, enum qeth_prot_versions proto)
767{
768 u8 addr[16];
769 int rc;
770
771 rc = qeth_l3_parse_vipae(buf, proto, addr);
772 if (rc)
773 return rc;
774
775 qeth_l3_del_vipa(card, proto, addr);
776
777 return count;
778}
779
780static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
781 struct device_attribute *attr, const char *buf, size_t count)
782{
783 struct qeth_card *card = dev_get_drvdata(dev);
784
785 if (!card)
786 return -EINVAL;
787
788 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
789}
790
791static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
792 qeth_l3_dev_vipa_del4_store);
793
794static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
795 struct device_attribute *attr, char *buf)
796{
797 struct qeth_card *card = dev_get_drvdata(dev);
798
799 if (!card)
800 return -EINVAL;
801
802 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
803}
804
805static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
806 struct device_attribute *attr, const char *buf, size_t count)
807{
808 struct qeth_card *card = dev_get_drvdata(dev);
809
810 if (!card)
811 return -EINVAL;
812
813 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
814}
815
816static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
817 qeth_l3_dev_vipa_add6_show,
818 qeth_l3_dev_vipa_add6_store);
819
820static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
821 struct device_attribute *attr, const char *buf, size_t count)
822{
823 struct qeth_card *card = dev_get_drvdata(dev);
824
825 if (!card)
826 return -EINVAL;
827
828 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
829}
830
831static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
832 qeth_l3_dev_vipa_del6_store);
833
834static struct attribute *qeth_vipa_device_attrs[] = {
835 &dev_attr_vipa_add4.attr,
836 &dev_attr_vipa_del4.attr,
837 &dev_attr_vipa_add6.attr,
838 &dev_attr_vipa_del6.attr,
839 NULL,
840};
841
842static struct attribute_group qeth_device_vipa_group = {
843 .name = "vipa",
844 .attrs = qeth_vipa_device_attrs,
845};
846
847static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
848 enum qeth_prot_versions proto)
849{
850 struct qeth_ipaddr *ipaddr;
851 char addr_str[40];
852 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
853 unsigned long flags;
854 int i = 0;
855
856 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
857 entry_len += 2; /* \n + terminator */
858 spin_lock_irqsave(&card->ip_lock, flags);
859 list_for_each_entry(ipaddr, &card->ip_list, entry) {
860 if (ipaddr->proto != proto)
861 continue;
862 if (ipaddr->type != QETH_IP_TYPE_RXIP)
863 continue;
864 /* String must not be longer than PAGE_SIZE. So we check if
865 * string length gets near PAGE_SIZE. Then we can savely display
866 * the next IPv6 address (worst case, compared to IPv4) */
867 if ((PAGE_SIZE - i) <= entry_len)
868 break;
869 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
870 addr_str);
871 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
872 }
873 spin_unlock_irqrestore(&card->ip_lock, flags);
874 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
875
876 return i;
877}
878
879static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
880 struct device_attribute *attr, char *buf)
881{
882 struct qeth_card *card = dev_get_drvdata(dev);
883
884 if (!card)
885 return -EINVAL;
886
887 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
888}
889
890static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
891 u8 *addr)
892{
893 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
894 PRINT_WARN("Invalid IP address format!\n");
895 return -EINVAL;
896 }
897 return 0;
898}
899
900static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
901 struct qeth_card *card, enum qeth_prot_versions proto)
902{
903 u8 addr[16] = {0, };
904 int rc;
905
906 rc = qeth_l3_parse_rxipe(buf, proto, addr);
907 if (rc)
908 return rc;
909
910 rc = qeth_l3_add_rxip(card, proto, addr);
911 if (rc)
912 return rc;
913
914 return count;
915}
916
917static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
918 struct device_attribute *attr, const char *buf, size_t count)
919{
920 struct qeth_card *card = dev_get_drvdata(dev);
921
922 if (!card)
923 return -EINVAL;
924
925 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
926}
927
928static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
929 qeth_l3_dev_rxip_add4_show,
930 qeth_l3_dev_rxip_add4_store);
931
932static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
933 struct qeth_card *card, enum qeth_prot_versions proto)
934{
935 u8 addr[16];
936 int rc;
937
938 rc = qeth_l3_parse_rxipe(buf, proto, addr);
939 if (rc)
940 return rc;
941
942 qeth_l3_del_rxip(card, proto, addr);
943
944 return count;
945}
946
947static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
948 struct device_attribute *attr, const char *buf, size_t count)
949{
950 struct qeth_card *card = dev_get_drvdata(dev);
951
952 if (!card)
953 return -EINVAL;
954
955 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
956}
957
958static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
959 qeth_l3_dev_rxip_del4_store);
960
961static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
962 struct device_attribute *attr, char *buf)
963{
964 struct qeth_card *card = dev_get_drvdata(dev);
965
966 if (!card)
967 return -EINVAL;
968
969 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
970}
971
972static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
973 struct device_attribute *attr, const char *buf, size_t count)
974{
975 struct qeth_card *card = dev_get_drvdata(dev);
976
977 if (!card)
978 return -EINVAL;
979
980 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
981}
982
983static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
984 qeth_l3_dev_rxip_add6_show,
985 qeth_l3_dev_rxip_add6_store);
986
987static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
988 struct device_attribute *attr, const char *buf, size_t count)
989{
990 struct qeth_card *card = dev_get_drvdata(dev);
991
992 if (!card)
993 return -EINVAL;
994
995 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
996}
997
998static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
999 qeth_l3_dev_rxip_del6_store);
1000
1001static struct attribute *qeth_rxip_device_attrs[] = {
1002 &dev_attr_rxip_add4.attr,
1003 &dev_attr_rxip_del4.attr,
1004 &dev_attr_rxip_add6.attr,
1005 &dev_attr_rxip_del6.attr,
1006 NULL,
1007};
1008
1009static struct attribute_group qeth_device_rxip_group = {
1010 .name = "rxip",
1011 .attrs = qeth_rxip_device_attrs,
1012};
1013
1014int qeth_l3_create_device_attributes(struct device *dev)
1015{
1016 int ret;
1017
1018 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1019 if (ret)
1020 return ret;
1021
1022 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1023 if (ret) {
1024 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1025 return ret;
1026 }
1027
1028 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1029 if (ret) {
1030 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1031 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1032 return ret;
1033 }
1034
1035 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1036 if (ret) {
1037 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1038 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1039 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1040 return ret;
1041 }
1042 return 0;
1043}
1044
1045void qeth_l3_remove_device_attributes(struct device *dev)
1046{
1047 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1048 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1049 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1050 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1051}
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
deleted file mode 100644
index d063e9ecf804..000000000000
--- a/drivers/s390/net/qeth_main.c
+++ /dev/null
@@ -1,8959 +0,0 @@
1/*
2 * linux/drivers/s390/net/qeth_main.c
3 *
4 * Linux on zSeries OSA Express and HiperSockets support
5 *
6 * Copyright 2000,2003 IBM Corporation
7 *
8 * Author(s): Original Code written by
9 * Utz Bacher (utz.bacher@de.ibm.com)
10 * Rewritten by
11 * Frank Pavlic (fpavlic@de.ibm.com) and
12 * Thomas Spatzier <tspat@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/string.h>
33#include <linux/errno.h>
34#include <linux/mm.h>
35#include <linux/ip.h>
36#include <linux/inetdevice.h>
37#include <linux/netdevice.h>
38#include <linux/sched.h>
39#include <linux/workqueue.h>
40#include <linux/kernel.h>
41#include <linux/slab.h>
42#include <linux/interrupt.h>
43#include <linux/tcp.h>
44#include <linux/icmp.h>
45#include <linux/skbuff.h>
46#include <linux/in.h>
47#include <linux/igmp.h>
48#include <linux/init.h>
49#include <linux/reboot.h>
50#include <linux/mii.h>
51#include <linux/rcupdate.h>
52#include <linux/ethtool.h>
53
54#include <net/arp.h>
55#include <net/ip.h>
56#include <net/route.h>
57
58#include <asm/ebcdic.h>
59#include <asm/io.h>
60#include <asm/qeth.h>
61#include <asm/timex.h>
62#include <asm/semaphore.h>
63#include <asm/uaccess.h>
64#include <asm/s390_rdev.h>
65
66#include "qeth.h"
67#include "qeth_mpc.h"
68#include "qeth_fs.h"
69#include "qeth_eddp.h"
70#include "qeth_tso.h"
71
72static const char *version = "qeth S/390 OSA-Express driver";
73
74/**
75 * Debug Facility Stuff
76 */
77static debug_info_t *qeth_dbf_setup = NULL;
78static debug_info_t *qeth_dbf_data = NULL;
79static debug_info_t *qeth_dbf_misc = NULL;
80static debug_info_t *qeth_dbf_control = NULL;
81debug_info_t *qeth_dbf_trace = NULL;
82static debug_info_t *qeth_dbf_sense = NULL;
83static debug_info_t *qeth_dbf_qerr = NULL;
84
85DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf);
86
87static struct lock_class_key qdio_out_skb_queue_key;
88
89/**
90 * some more definitions and declarations
91 */
92static unsigned int known_devices[][10] = QETH_MODELLIST_ARRAY;
93
94/* list of our cards */
95struct qeth_card_list_struct qeth_card_list;
96/*process list want to be notified*/
97spinlock_t qeth_notify_lock;
98struct list_head qeth_notify_list;
99
100static void qeth_send_control_data_cb(struct qeth_channel *,
101 struct qeth_cmd_buffer *);
102
103/**
104 * here we go with function implementation
105 */
106static void
107qeth_init_qdio_info(struct qeth_card *card);
108
109static int
110qeth_init_qdio_queues(struct qeth_card *card);
111
112static int
113qeth_alloc_qdio_buffers(struct qeth_card *card);
114
115static void
116qeth_free_qdio_buffers(struct qeth_card *);
117
118static void
119qeth_clear_qdio_buffers(struct qeth_card *);
120
121static void
122qeth_clear_ip_list(struct qeth_card *, int, int);
123
124static void
125qeth_clear_ipacmd_list(struct qeth_card *);
126
127static int
128qeth_qdio_clear_card(struct qeth_card *, int);
129
130static void
131qeth_clear_working_pool_list(struct qeth_card *);
132
133static void
134qeth_clear_cmd_buffers(struct qeth_channel *);
135
136static int
137qeth_stop(struct net_device *);
138
139static void
140qeth_clear_ipato_list(struct qeth_card *);
141
142static int
143qeth_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
144
145static void
146qeth_irq_tasklet(unsigned long);
147
148static int
149qeth_set_online(struct ccwgroup_device *);
150
151static int
152__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode);
153
154static struct qeth_ipaddr *
155qeth_get_addr_buffer(enum qeth_prot_versions);
156
157static void
158qeth_set_multicast_list(struct net_device *);
159
160static void
161qeth_setadp_promisc_mode(struct qeth_card *);
162
163static int
164qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr);
165
166static void
167qeth_notify_processes(void)
168{
169 /*notify all registered processes */
170 struct qeth_notify_list_struct *n_entry;
171
172 QETH_DBF_TEXT(trace,3,"procnoti");
173 spin_lock(&qeth_notify_lock);
174 list_for_each_entry(n_entry, &qeth_notify_list, list) {
175 send_sig(n_entry->signum, n_entry->task, 1);
176 }
177 spin_unlock(&qeth_notify_lock);
178
179}
180int
181qeth_notifier_unregister(struct task_struct *p)
182{
183 struct qeth_notify_list_struct *n_entry, *tmp;
184
185 QETH_DBF_TEXT(trace, 2, "notunreg");
186 spin_lock(&qeth_notify_lock);
187 list_for_each_entry_safe(n_entry, tmp, &qeth_notify_list, list) {
188 if (n_entry->task == p) {
189 list_del(&n_entry->list);
190 kfree(n_entry);
191 goto out;
192 }
193 }
194out:
195 spin_unlock(&qeth_notify_lock);
196 return 0;
197}
198int
199qeth_notifier_register(struct task_struct *p, int signum)
200{
201 struct qeth_notify_list_struct *n_entry;
202
203 /*check first if entry already exists*/
204 spin_lock(&qeth_notify_lock);
205 list_for_each_entry(n_entry, &qeth_notify_list, list) {
206 if (n_entry->task == p) {
207 n_entry->signum = signum;
208 spin_unlock(&qeth_notify_lock);
209 return 0;
210 }
211 }
212 spin_unlock(&qeth_notify_lock);
213
214 n_entry = (struct qeth_notify_list_struct *)
215 kmalloc(sizeof(struct qeth_notify_list_struct),GFP_KERNEL);
216 if (!n_entry)
217 return -ENOMEM;
218 n_entry->task = p;
219 n_entry->signum = signum;
220 spin_lock(&qeth_notify_lock);
221 list_add(&n_entry->list,&qeth_notify_list);
222 spin_unlock(&qeth_notify_lock);
223 return 0;
224}
225
226
227/**
228 * free channel command buffers
229 */
230static void
231qeth_clean_channel(struct qeth_channel *channel)
232{
233 int cnt;
234
235 QETH_DBF_TEXT(setup, 2, "freech");
236 for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++)
237 kfree(channel->iob[cnt].data);
238}
239
240/**
241 * free card
242 */
243static void
244qeth_free_card(struct qeth_card *card)
245{
246
247 QETH_DBF_TEXT(setup, 2, "freecrd");
248 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
249 qeth_clean_channel(&card->read);
250 qeth_clean_channel(&card->write);
251 if (card->dev)
252 free_netdev(card->dev);
253 qeth_clear_ip_list(card, 0, 0);
254 qeth_clear_ipato_list(card);
255 kfree(card->ip_tbd_list);
256 qeth_free_qdio_buffers(card);
257 kfree(card);
258}
259
260/**
261 * alloc memory for command buffer per channel
262 */
263static int
264qeth_setup_channel(struct qeth_channel *channel)
265{
266 int cnt;
267
268 QETH_DBF_TEXT(setup, 2, "setupch");
269 for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++) {
270 channel->iob[cnt].data = (char *)
271 kmalloc(QETH_BUFSIZE, GFP_DMA|GFP_KERNEL);
272 if (channel->iob[cnt].data == NULL)
273 break;
274 channel->iob[cnt].state = BUF_STATE_FREE;
275 channel->iob[cnt].channel = channel;
276 channel->iob[cnt].callback = qeth_send_control_data_cb;
277 channel->iob[cnt].rc = 0;
278 }
279 if (cnt < QETH_CMD_BUFFER_NO) {
280 while (cnt-- > 0)
281 kfree(channel->iob[cnt].data);
282 return -ENOMEM;
283 }
284 channel->buf_no = 0;
285 channel->io_buf_no = 0;
286 atomic_set(&channel->irq_pending, 0);
287 spin_lock_init(&channel->iob_lock);
288
289 init_waitqueue_head(&channel->wait_q);
290 channel->irq_tasklet.data = (unsigned long) channel;
291 channel->irq_tasklet.func = qeth_irq_tasklet;
292 return 0;
293}
294
295/**
296 * alloc memory for card structure
297 */
298static struct qeth_card *
299qeth_alloc_card(void)
300{
301 struct qeth_card *card;
302
303 QETH_DBF_TEXT(setup, 2, "alloccrd");
304 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
305 if (!card)
306 return NULL;
307 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
308 if (qeth_setup_channel(&card->read)) {
309 kfree(card);
310 return NULL;
311 }
312 if (qeth_setup_channel(&card->write)) {
313 qeth_clean_channel(&card->read);
314 kfree(card);
315 return NULL;
316 }
317 return card;
318}
319
320static long
321__qeth_check_irb_error(struct ccw_device *cdev, unsigned long intparm,
322 struct irb *irb)
323{
324 if (!IS_ERR(irb))
325 return 0;
326
327 switch (PTR_ERR(irb)) {
328 case -EIO:
329 PRINT_WARN("i/o-error on device %s\n", cdev->dev.bus_id);
330 QETH_DBF_TEXT(trace, 2, "ckirberr");
331 QETH_DBF_TEXT_(trace, 2, " rc%d", -EIO);
332 break;
333 case -ETIMEDOUT:
334 PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id);
335 QETH_DBF_TEXT(trace, 2, "ckirberr");
336 QETH_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT);
337 if (intparm == QETH_RCD_PARM) {
338 struct qeth_card *card = CARD_FROM_CDEV(cdev);
339
340 if (card && (card->data.ccwdev == cdev)) {
341 card->data.state = CH_STATE_DOWN;
342 wake_up(&card->wait_q);
343 }
344 }
345 break;
346 default:
347 PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb),
348 cdev->dev.bus_id);
349 QETH_DBF_TEXT(trace, 2, "ckirberr");
350 QETH_DBF_TEXT(trace, 2, " rc???");
351 }
352 return PTR_ERR(irb);
353}
354
355static int
356qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
357{
358 int dstat,cstat;
359 char *sense;
360
361 sense = (char *) irb->ecw;
362 cstat = irb->scsw.cstat;
363 dstat = irb->scsw.dstat;
364
365 if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
366 SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
367 SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
368 QETH_DBF_TEXT(trace,2, "CGENCHK");
369 PRINT_WARN("check on device %s, dstat=x%x, cstat=x%x ",
370 cdev->dev.bus_id, dstat, cstat);
371 HEXDUMP16(WARN, "irb: ", irb);
372 HEXDUMP16(WARN, "irb: ", ((char *) irb) + 32);
373 return 1;
374 }
375
376 if (dstat & DEV_STAT_UNIT_CHECK) {
377 if (sense[SENSE_RESETTING_EVENT_BYTE] &
378 SENSE_RESETTING_EVENT_FLAG) {
379 QETH_DBF_TEXT(trace,2,"REVIND");
380 return 1;
381 }
382 if (sense[SENSE_COMMAND_REJECT_BYTE] &
383 SENSE_COMMAND_REJECT_FLAG) {
384 QETH_DBF_TEXT(trace,2,"CMDREJi");
385 return 0;
386 }
387 if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) {
388 QETH_DBF_TEXT(trace,2,"AFFE");
389 return 1;
390 }
391 if ((!sense[0]) && (!sense[1]) && (!sense[2]) && (!sense[3])) {
392 QETH_DBF_TEXT(trace,2,"ZEROSEN");
393 return 0;
394 }
395 QETH_DBF_TEXT(trace,2,"DGENCHK");
396 return 1;
397 }
398 return 0;
399}
400static int qeth_issue_next_read(struct qeth_card *);
401
402/**
403 * interrupt handler
404 */
405static void
406qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
407{
408 int rc;
409 int cstat,dstat;
410 struct qeth_cmd_buffer *buffer;
411 struct qeth_channel *channel;
412 struct qeth_card *card;
413
414 QETH_DBF_TEXT(trace,5,"irq");
415
416 if (__qeth_check_irb_error(cdev, intparm, irb))
417 return;
418 cstat = irb->scsw.cstat;
419 dstat = irb->scsw.dstat;
420
421 card = CARD_FROM_CDEV(cdev);
422 if (!card)
423 return;
424
425 if (card->read.ccwdev == cdev){
426 channel = &card->read;
427 QETH_DBF_TEXT(trace,5,"read");
428 } else if (card->write.ccwdev == cdev) {
429 channel = &card->write;
430 QETH_DBF_TEXT(trace,5,"write");
431 } else {
432 channel = &card->data;
433 QETH_DBF_TEXT(trace,5,"data");
434 }
435 atomic_set(&channel->irq_pending, 0);
436
437 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC))
438 channel->state = CH_STATE_STOPPED;
439
440 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC))
441 channel->state = CH_STATE_HALTED;
442
443 /*let's wake up immediately on data channel*/
444 if ((channel == &card->data) && (intparm != 0) &&
445 (intparm != QETH_RCD_PARM))
446 goto out;
447
448 if (intparm == QETH_CLEAR_CHANNEL_PARM) {
449 QETH_DBF_TEXT(trace, 6, "clrchpar");
450 /* we don't have to handle this further */
451 intparm = 0;
452 }
453 if (intparm == QETH_HALT_CHANNEL_PARM) {
454 QETH_DBF_TEXT(trace, 6, "hltchpar");
455 /* we don't have to handle this further */
456 intparm = 0;
457 }
458 if ((dstat & DEV_STAT_UNIT_EXCEP) ||
459 (dstat & DEV_STAT_UNIT_CHECK) ||
460 (cstat)) {
461 if (irb->esw.esw0.erw.cons) {
462 /* TODO: we should make this s390dbf */
463 PRINT_WARN("sense data available on channel %s.\n",
464 CHANNEL_ID(channel));
465 PRINT_WARN(" cstat 0x%X\n dstat 0x%X\n", cstat, dstat);
466 HEXDUMP16(WARN,"irb: ",irb);
467 HEXDUMP16(WARN,"sense data: ",irb->ecw);
468 }
469 if (intparm == QETH_RCD_PARM) {
470 channel->state = CH_STATE_DOWN;
471 goto out;
472 }
473 rc = qeth_get_problem(cdev,irb);
474 if (rc) {
475 qeth_schedule_recovery(card);
476 goto out;
477 }
478 }
479
480 if (intparm == QETH_RCD_PARM) {
481 channel->state = CH_STATE_RCD_DONE;
482 goto out;
483 }
484 if (intparm) {
485 buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
486 buffer->state = BUF_STATE_PROCESSED;
487 }
488 if (channel == &card->data)
489 return;
490
491 if (channel == &card->read &&
492 channel->state == CH_STATE_UP)
493 qeth_issue_next_read(card);
494
495 qeth_irq_tasklet((unsigned long)channel);
496 return;
497out:
498 wake_up(&card->wait_q);
499}
500
501/**
502 * tasklet function scheduled from irq handler
503 */
504static void
505qeth_irq_tasklet(unsigned long data)
506{
507 struct qeth_card *card;
508 struct qeth_channel *channel;
509 struct qeth_cmd_buffer *iob;
510 __u8 index;
511
512 QETH_DBF_TEXT(trace,5,"irqtlet");
513 channel = (struct qeth_channel *) data;
514 iob = channel->iob;
515 index = channel->buf_no;
516 card = CARD_FROM_CDEV(channel->ccwdev);
517 while (iob[index].state == BUF_STATE_PROCESSED) {
518 if (iob[index].callback !=NULL) {
519 iob[index].callback(channel,iob + index);
520 }
521 index = (index + 1) % QETH_CMD_BUFFER_NO;
522 }
523 channel->buf_no = index;
524 wake_up(&card->wait_q);
525}
526
527static int qeth_stop_card(struct qeth_card *, int);
528
529static int
530__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
531{
532 struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
533 int rc = 0, rc2 = 0, rc3 = 0;
534 enum qeth_card_states recover_flag;
535
536 QETH_DBF_TEXT(setup, 3, "setoffl");
537 QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
538
539 if (card->dev && netif_carrier_ok(card->dev))
540 netif_carrier_off(card->dev);
541 recover_flag = card->state;
542 if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){
543 PRINT_WARN("Stopping card %s interrupted by user!\n",
544 CARD_BUS_ID(card));
545 return -ERESTARTSYS;
546 }
547 rc = ccw_device_set_offline(CARD_DDEV(card));
548 rc2 = ccw_device_set_offline(CARD_WDEV(card));
549 rc3 = ccw_device_set_offline(CARD_RDEV(card));
550 if (!rc)
551 rc = (rc2) ? rc2 : rc3;
552 if (rc)
553 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
554 if (recover_flag == CARD_STATE_UP)
555 card->state = CARD_STATE_RECOVER;
556 qeth_notify_processes();
557 return 0;
558}
559
560static int
561qeth_set_offline(struct ccwgroup_device *cgdev)
562{
563 return __qeth_set_offline(cgdev, 0);
564}
565
566static int
567qeth_threads_running(struct qeth_card *card, unsigned long threads);
568
569
570static void
571qeth_remove_device(struct ccwgroup_device *cgdev)
572{
573 struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
574 unsigned long flags;
575
576 QETH_DBF_TEXT(setup, 3, "rmdev");
577 QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
578
579 if (!card)
580 return;
581
582 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
583
584 if (cgdev->state == CCWGROUP_ONLINE){
585 card->use_hard_stop = 1;
586 qeth_set_offline(cgdev);
587 }
588 /* remove form our internal list */
589 write_lock_irqsave(&qeth_card_list.rwlock, flags);
590 list_del(&card->list);
591 write_unlock_irqrestore(&qeth_card_list.rwlock, flags);
592 if (card->dev)
593 unregister_netdev(card->dev);
594 qeth_remove_device_attributes(&cgdev->dev);
595 qeth_free_card(card);
596 cgdev->dev.driver_data = NULL;
597 put_device(&cgdev->dev);
598}
599
600static int
601qeth_register_addr_entry(struct qeth_card *, struct qeth_ipaddr *);
602static int
603qeth_deregister_addr_entry(struct qeth_card *, struct qeth_ipaddr *);
604
605/**
606 * Add/remove address to/from card's ip list, i.e. try to add or remove
607 * reference to/from an IP address that is already registered on the card.
608 * Returns:
609 * 0 address was on card and its reference count has been adjusted,
610 * but is still > 0, so nothing has to be done
611 * also returns 0 if card was not on card and the todo was to delete
612 * the address -> there is also nothing to be done
613 * 1 address was not on card and the todo is to add it to the card's ip
614 * list
615 * -1 address was on card and its reference count has been decremented
616 * to <= 0 by the todo -> address must be removed from card
617 */
618static int
619__qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
620 struct qeth_ipaddr **__addr)
621{
622 struct qeth_ipaddr *addr;
623 int found = 0;
624
625 list_for_each_entry(addr, &card->ip_list, entry) {
626 if (card->options.layer2) {
627 if ((addr->type == todo->type) &&
628 (memcmp(&addr->mac, &todo->mac,
629 OSA_ADDR_LEN) == 0)) {
630 found = 1;
631 break;
632 }
633 continue;
634 }
635 if ((addr->proto == QETH_PROT_IPV4) &&
636 (todo->proto == QETH_PROT_IPV4) &&
637 (addr->type == todo->type) &&
638 (addr->u.a4.addr == todo->u.a4.addr) &&
639 (addr->u.a4.mask == todo->u.a4.mask)) {
640 found = 1;
641 break;
642 }
643 if ((addr->proto == QETH_PROT_IPV6) &&
644 (todo->proto == QETH_PROT_IPV6) &&
645 (addr->type == todo->type) &&
646 (addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&
647 (memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
648 sizeof(struct in6_addr)) == 0)) {
649 found = 1;
650 break;
651 }
652 }
653 if (found) {
654 addr->users += todo->users;
655 if (addr->users <= 0){
656 *__addr = addr;
657 return -1;
658 } else {
659 /* for VIPA and RXIP limit refcount to 1 */
660 if (addr->type != QETH_IP_TYPE_NORMAL)
661 addr->users = 1;
662 return 0;
663 }
664 }
665 if (todo->users > 0) {
666 /* for VIPA and RXIP limit refcount to 1 */
667 if (todo->type != QETH_IP_TYPE_NORMAL)
668 todo->users = 1;
669 return 1;
670 } else
671 return 0;
672}
673
674static int
675__qeth_address_exists_in_list(struct list_head *list, struct qeth_ipaddr *addr,
676 int same_type)
677{
678 struct qeth_ipaddr *tmp;
679
680 list_for_each_entry(tmp, list, entry) {
681 if ((tmp->proto == QETH_PROT_IPV4) &&
682 (addr->proto == QETH_PROT_IPV4) &&
683 ((same_type && (tmp->type == addr->type)) ||
684 (!same_type && (tmp->type != addr->type)) ) &&
685 (tmp->u.a4.addr == addr->u.a4.addr) ){
686 return 1;
687 }
688 if ((tmp->proto == QETH_PROT_IPV6) &&
689 (addr->proto == QETH_PROT_IPV6) &&
690 ((same_type && (tmp->type == addr->type)) ||
691 (!same_type && (tmp->type != addr->type)) ) &&
692 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
693 sizeof(struct in6_addr)) == 0) ) {
694 return 1;
695 }
696 }
697 return 0;
698}
699
700/*
701 * Add IP to be added to todo list. If there is already an "add todo"
702 * in this list we just incremenent the reference count.
703 * Returns 0 if we just incremented reference count.
704 */
705static int
706__qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
707{
708 struct qeth_ipaddr *tmp, *t;
709 int found = 0;
710
711 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
712 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
713 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
714 return 0;
715 if (card->options.layer2) {
716 if ((tmp->type == addr->type) &&
717 (tmp->is_multicast == addr->is_multicast) &&
718 (memcmp(&tmp->mac, &addr->mac,
719 OSA_ADDR_LEN) == 0)) {
720 found = 1;
721 break;
722 }
723 continue;
724 }
725 if ((tmp->proto == QETH_PROT_IPV4) &&
726 (addr->proto == QETH_PROT_IPV4) &&
727 (tmp->type == addr->type) &&
728 (tmp->is_multicast == addr->is_multicast) &&
729 (tmp->u.a4.addr == addr->u.a4.addr) &&
730 (tmp->u.a4.mask == addr->u.a4.mask)) {
731 found = 1;
732 break;
733 }
734 if ((tmp->proto == QETH_PROT_IPV6) &&
735 (addr->proto == QETH_PROT_IPV6) &&
736 (tmp->type == addr->type) &&
737 (tmp->is_multicast == addr->is_multicast) &&
738 (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) &&
739 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
740 sizeof(struct in6_addr)) == 0)) {
741 found = 1;
742 break;
743 }
744 }
745 if (found){
746 if (addr->users != 0)
747 tmp->users += addr->users;
748 else
749 tmp->users += add? 1:-1;
750 if (tmp->users == 0) {
751 list_del(&tmp->entry);
752 kfree(tmp);
753 }
754 return 0;
755 } else {
756 if (addr->type == QETH_IP_TYPE_DEL_ALL_MC)
757 list_add(&addr->entry, card->ip_tbd_list);
758 else {
759 if (addr->users == 0)
760 addr->users += add? 1:-1;
761 if (add && (addr->type == QETH_IP_TYPE_NORMAL) &&
762 qeth_is_addr_covered_by_ipato(card, addr)){
763 QETH_DBF_TEXT(trace, 2, "tkovaddr");
764 addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
765 }
766 list_add_tail(&addr->entry, card->ip_tbd_list);
767 }
768 return 1;
769 }
770}
771
772/**
773 * Remove IP address from list
774 */
775static int
776qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
777{
778 unsigned long flags;
779 int rc = 0;
780
781 QETH_DBF_TEXT(trace, 4, "delip");
782
783 if (card->options.layer2)
784 QETH_DBF_HEX(trace, 4, &addr->mac, 6);
785 else if (addr->proto == QETH_PROT_IPV4)
786 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
787 else {
788 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
789 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
790 }
791 spin_lock_irqsave(&card->ip_lock, flags);
792 rc = __qeth_insert_ip_todo(card, addr, 0);
793 spin_unlock_irqrestore(&card->ip_lock, flags);
794 return rc;
795}
796
797static int
798qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
799{
800 unsigned long flags;
801 int rc = 0;
802
803 QETH_DBF_TEXT(trace, 4, "addip");
804 if (card->options.layer2)
805 QETH_DBF_HEX(trace, 4, &addr->mac, 6);
806 else if (addr->proto == QETH_PROT_IPV4)
807 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
808 else {
809 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
810 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
811 }
812 spin_lock_irqsave(&card->ip_lock, flags);
813 rc = __qeth_insert_ip_todo(card, addr, 1);
814 spin_unlock_irqrestore(&card->ip_lock, flags);
815 return rc;
816}
817
818static void
819__qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
820{
821 struct qeth_ipaddr *addr, *tmp;
822 int rc;
823again:
824 list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
825 if (addr->is_multicast) {
826 list_del(&addr->entry);
827 spin_unlock_irqrestore(&card->ip_lock, *flags);
828 rc = qeth_deregister_addr_entry(card, addr);
829 spin_lock_irqsave(&card->ip_lock, *flags);
830 if (!rc) {
831 kfree(addr);
832 goto again;
833 } else
834 list_add(&addr->entry, &card->ip_list);
835 }
836 }
837}
838
839static void
840qeth_set_ip_addr_list(struct qeth_card *card)
841{
842 struct list_head *tbd_list;
843 struct qeth_ipaddr *todo, *addr;
844 unsigned long flags;
845 int rc;
846
847 QETH_DBF_TEXT(trace, 2, "sdiplist");
848 QETH_DBF_HEX(trace, 2, &card, sizeof(void *));
849
850 spin_lock_irqsave(&card->ip_lock, flags);
851 tbd_list = card->ip_tbd_list;
852 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
853 if (!card->ip_tbd_list) {
854 QETH_DBF_TEXT(trace, 0, "silnomem");
855 card->ip_tbd_list = tbd_list;
856 spin_unlock_irqrestore(&card->ip_lock, flags);
857 return;
858 } else
859 INIT_LIST_HEAD(card->ip_tbd_list);
860
861 while (!list_empty(tbd_list)){
862 todo = list_entry(tbd_list->next, struct qeth_ipaddr, entry);
863 list_del(&todo->entry);
864 if (todo->type == QETH_IP_TYPE_DEL_ALL_MC){
865 __qeth_delete_all_mc(card, &flags);
866 kfree(todo);
867 continue;
868 }
869 rc = __qeth_ref_ip_on_card(card, todo, &addr);
870 if (rc == 0) {
871 /* nothing to be done; only adjusted refcount */
872 kfree(todo);
873 } else if (rc == 1) {
874 /* new entry to be added to on-card list */
875 spin_unlock_irqrestore(&card->ip_lock, flags);
876 rc = qeth_register_addr_entry(card, todo);
877 spin_lock_irqsave(&card->ip_lock, flags);
878 if (!rc)
879 list_add_tail(&todo->entry, &card->ip_list);
880 else
881 kfree(todo);
882 } else if (rc == -1) {
883 /* on-card entry to be removed */
884 list_del_init(&addr->entry);
885 spin_unlock_irqrestore(&card->ip_lock, flags);
886 rc = qeth_deregister_addr_entry(card, addr);
887 spin_lock_irqsave(&card->ip_lock, flags);
888 if (!rc)
889 kfree(addr);
890 else
891 list_add_tail(&addr->entry, &card->ip_list);
892 kfree(todo);
893 }
894 }
895 spin_unlock_irqrestore(&card->ip_lock, flags);
896 kfree(tbd_list);
897}
898
899static void qeth_delete_mc_addresses(struct qeth_card *);
900static void qeth_add_multicast_ipv4(struct qeth_card *);
901static void qeth_layer2_add_multicast(struct qeth_card *);
902#ifdef CONFIG_QETH_IPV6
903static void qeth_add_multicast_ipv6(struct qeth_card *);
904#endif
905
906static int
907qeth_set_thread_start_bit(struct qeth_card *card, unsigned long thread)
908{
909 unsigned long flags;
910
911 spin_lock_irqsave(&card->thread_mask_lock, flags);
912 if ( !(card->thread_allowed_mask & thread) ||
913 (card->thread_start_mask & thread) ) {
914 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
915 return -EPERM;
916 }
917 card->thread_start_mask |= thread;
918 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
919 return 0;
920}
921
922static void
923qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread)
924{
925 unsigned long flags;
926
927 spin_lock_irqsave(&card->thread_mask_lock, flags);
928 card->thread_start_mask &= ~thread;
929 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
930 wake_up(&card->wait_q);
931}
932
933static void
934qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
935{
936 unsigned long flags;
937
938 spin_lock_irqsave(&card->thread_mask_lock, flags);
939 card->thread_running_mask &= ~thread;
940 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
941 wake_up(&card->wait_q);
942}
943
944static int
945__qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
946{
947 unsigned long flags;
948 int rc = 0;
949
950 spin_lock_irqsave(&card->thread_mask_lock, flags);
951 if (card->thread_start_mask & thread){
952 if ((card->thread_allowed_mask & thread) &&
953 !(card->thread_running_mask & thread)){
954 rc = 1;
955 card->thread_start_mask &= ~thread;
956 card->thread_running_mask |= thread;
957 } else
958 rc = -EPERM;
959 }
960 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
961 return rc;
962}
963
964static int
965qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
966{
967 int rc = 0;
968
969 wait_event(card->wait_q,
970 (rc = __qeth_do_run_thread(card, thread)) >= 0);
971 return rc;
972}
973
974static int
975qeth_recover(void *ptr)
976{
977 struct qeth_card *card;
978 int rc = 0;
979
980 card = (struct qeth_card *) ptr;
981 daemonize("qeth_recover");
982 QETH_DBF_TEXT(trace,2,"recover1");
983 QETH_DBF_HEX(trace, 2, &card, sizeof(void *));
984 if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
985 return 0;
986 QETH_DBF_TEXT(trace,2,"recover2");
987 PRINT_WARN("Recovery of device %s started ...\n",
988 CARD_BUS_ID(card));
989 card->use_hard_stop = 1;
990 __qeth_set_offline(card->gdev,1);
991 rc = __qeth_set_online(card->gdev,1);
992 /* don't run another scheduled recovery */
993 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
994 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
995 if (!rc)
996 PRINT_INFO("Device %s successfully recovered!\n",
997 CARD_BUS_ID(card));
998 else
999 PRINT_INFO("Device %s could not be recovered!\n",
1000 CARD_BUS_ID(card));
1001 return 0;
1002}
1003
1004void
1005qeth_schedule_recovery(struct qeth_card *card)
1006{
1007 QETH_DBF_TEXT(trace,2,"startrec");
1008 if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
1009 schedule_work(&card->kernel_thread_starter);
1010}
1011
1012static int
1013qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
1014{
1015 unsigned long flags;
1016 int rc = 0;
1017
1018 spin_lock_irqsave(&card->thread_mask_lock, flags);
1019 QETH_DBF_TEXT_(trace, 4, " %02x%02x%02x",
1020 (u8) card->thread_start_mask,
1021 (u8) card->thread_allowed_mask,
1022 (u8) card->thread_running_mask);
1023 rc = (card->thread_start_mask & thread);
1024 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
1025 return rc;
1026}
1027
1028static void
1029qeth_start_kernel_thread(struct work_struct *work)
1030{
1031 struct qeth_card *card = container_of(work, struct qeth_card, kernel_thread_starter);
1032 QETH_DBF_TEXT(trace , 2, "strthrd");
1033
1034 if (card->read.state != CH_STATE_UP &&
1035 card->write.state != CH_STATE_UP)
1036 return;
1037 if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
1038 kernel_thread(qeth_recover, (void *) card, SIGCHLD);
1039}
1040
1041
1042static void
1043qeth_set_intial_options(struct qeth_card *card)
1044{
1045 card->options.route4.type = NO_ROUTER;
1046#ifdef CONFIG_QETH_IPV6
1047 card->options.route6.type = NO_ROUTER;
1048#endif /* QETH_IPV6 */
1049 card->options.checksum_type = QETH_CHECKSUM_DEFAULT;
1050 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
1051 card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
1052 card->options.fake_broadcast = 0;
1053 card->options.add_hhlen = DEFAULT_ADD_HHLEN;
1054 card->options.fake_ll = 0;
1055 if (card->info.type == QETH_CARD_TYPE_OSN)
1056 card->options.layer2 = 1;
1057 else
1058 card->options.layer2 = 0;
1059 card->options.performance_stats = 0;
1060 card->options.rx_sg_cb = QETH_RX_SG_CB;
1061}
1062
1063/**
1064 * initialize channels ,card and all state machines
1065 */
1066static int
1067qeth_setup_card(struct qeth_card *card)
1068{
1069
1070 QETH_DBF_TEXT(setup, 2, "setupcrd");
1071 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
1072
1073 card->read.state = CH_STATE_DOWN;
1074 card->write.state = CH_STATE_DOWN;
1075 card->data.state = CH_STATE_DOWN;
1076 card->state = CARD_STATE_DOWN;
1077 card->lan_online = 0;
1078 card->use_hard_stop = 0;
1079 card->dev = NULL;
1080#ifdef CONFIG_QETH_VLAN
1081 spin_lock_init(&card->vlanlock);
1082 card->vlangrp = NULL;
1083#endif
1084 spin_lock_init(&card->lock);
1085 spin_lock_init(&card->ip_lock);
1086 spin_lock_init(&card->thread_mask_lock);
1087 card->thread_start_mask = 0;
1088 card->thread_allowed_mask = 0;
1089 card->thread_running_mask = 0;
1090 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
1091 INIT_LIST_HEAD(&card->ip_list);
1092 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1093 if (!card->ip_tbd_list) {
1094 QETH_DBF_TEXT(setup, 0, "iptbdnom");
1095 return -ENOMEM;
1096 }
1097 INIT_LIST_HEAD(card->ip_tbd_list);
1098 INIT_LIST_HEAD(&card->cmd_waiter_list);
1099 init_waitqueue_head(&card->wait_q);
1100 /* intial options */
1101 qeth_set_intial_options(card);
1102 /* IP address takeover */
1103 INIT_LIST_HEAD(&card->ipato.entries);
1104 card->ipato.enabled = 0;
1105 card->ipato.invert4 = 0;
1106 card->ipato.invert6 = 0;
1107 /* init QDIO stuff */
1108 qeth_init_qdio_info(card);
1109 return 0;
1110}
1111
1112static int
1113is_1920_device (struct qeth_card *card)
1114{
1115 int single_queue = 0;
1116 struct ccw_device *ccwdev;
1117 struct channelPath_dsc {
1118 u8 flags;
1119 u8 lsn;
1120 u8 desc;
1121 u8 chpid;
1122 u8 swla;
1123 u8 zeroes;
1124 u8 chla;
1125 u8 chpp;
1126 } *chp_dsc;
1127
1128 QETH_DBF_TEXT(setup, 2, "chk_1920");
1129
1130 ccwdev = card->data.ccwdev;
1131 chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0);
1132 if (chp_dsc != NULL) {
1133 /* CHPP field bit 6 == 1 -> single queue */
1134 single_queue = ((chp_dsc->chpp & 0x02) == 0x02);
1135 kfree(chp_dsc);
1136 }
1137 QETH_DBF_TEXT_(setup, 2, "rc:%x", single_queue);
1138 return single_queue;
1139}
1140
1141static int
1142qeth_determine_card_type(struct qeth_card *card)
1143{
1144 int i = 0;
1145
1146 QETH_DBF_TEXT(setup, 2, "detcdtyp");
1147
1148 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
1149 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
1150 while (known_devices[i][4]) {
1151 if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
1152 (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
1153 card->info.type = known_devices[i][4];
1154 card->qdio.no_out_queues = known_devices[i][8];
1155 card->info.is_multicast_different = known_devices[i][9];
1156 if (is_1920_device(card)) {
1157 PRINT_INFO("Priority Queueing not able "
1158 "due to hardware limitations!\n");
1159 card->qdio.no_out_queues = 1;
1160 card->qdio.default_out_queue = 0;
1161 }
1162 return 0;
1163 }
1164 i++;
1165 }
1166 card->info.type = QETH_CARD_TYPE_UNKNOWN;
1167 PRINT_ERR("unknown card type on device %s\n", CARD_BUS_ID(card));
1168 return -ENOENT;
1169}
1170
1171static int
1172qeth_probe_device(struct ccwgroup_device *gdev)
1173{
1174 struct qeth_card *card;
1175 struct device *dev;
1176 unsigned long flags;
1177 int rc;
1178
1179 QETH_DBF_TEXT(setup, 2, "probedev");
1180
1181 dev = &gdev->dev;
1182 if (!get_device(dev))
1183 return -ENODEV;
1184
1185 QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
1186
1187 card = qeth_alloc_card();
1188 if (!card) {
1189 put_device(dev);
1190 QETH_DBF_TEXT_(setup, 2, "1err%d", -ENOMEM);
1191 return -ENOMEM;
1192 }
1193 card->read.ccwdev = gdev->cdev[0];
1194 card->write.ccwdev = gdev->cdev[1];
1195 card->data.ccwdev = gdev->cdev[2];
1196 gdev->dev.driver_data = card;
1197 card->gdev = gdev;
1198 gdev->cdev[0]->handler = qeth_irq;
1199 gdev->cdev[1]->handler = qeth_irq;
1200 gdev->cdev[2]->handler = qeth_irq;
1201
1202 if ((rc = qeth_determine_card_type(card))){
1203 PRINT_WARN("%s: not a valid card type\n", __func__);
1204 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
1205 put_device(dev);
1206 qeth_free_card(card);
1207 return rc;
1208 }
1209 if ((rc = qeth_setup_card(card))){
1210 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
1211 put_device(dev);
1212 qeth_free_card(card);
1213 return rc;
1214 }
1215 rc = qeth_create_device_attributes(dev);
1216 if (rc) {
1217 put_device(dev);
1218 qeth_free_card(card);
1219 return rc;
1220 }
1221 /* insert into our internal list */
1222 write_lock_irqsave(&qeth_card_list.rwlock, flags);
1223 list_add_tail(&card->list, &qeth_card_list.list);
1224 write_unlock_irqrestore(&qeth_card_list.rwlock, flags);
1225 return rc;
1226}
1227
1228
1229static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
1230 int *length)
1231{
1232 struct ciw *ciw;
1233 char *rcd_buf;
1234 int ret;
1235 struct qeth_channel *channel = &card->data;
1236 unsigned long flags;
1237
1238 /*
1239 * scan for RCD command in extended SenseID data
1240 */
1241 ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD);
1242 if (!ciw || ciw->cmd == 0)
1243 return -EOPNOTSUPP;
1244 rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
1245 if (!rcd_buf)
1246 return -ENOMEM;
1247
1248 channel->ccw.cmd_code = ciw->cmd;
1249 channel->ccw.cda = (__u32) __pa (rcd_buf);
1250 channel->ccw.count = ciw->count;
1251 channel->ccw.flags = CCW_FLAG_SLI;
1252 channel->state = CH_STATE_RCD;
1253 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1254 ret = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
1255 QETH_RCD_PARM, LPM_ANYPATH, 0,
1256 QETH_RCD_TIMEOUT);
1257 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1258 if (!ret)
1259 wait_event(card->wait_q,
1260 (channel->state == CH_STATE_RCD_DONE ||
1261 channel->state == CH_STATE_DOWN));
1262 if (channel->state == CH_STATE_DOWN)
1263 ret = -EIO;
1264 else
1265 channel->state = CH_STATE_DOWN;
1266 if (ret) {
1267 kfree(rcd_buf);
1268 *buffer = NULL;
1269 *length = 0;
1270 } else {
1271 *length = ciw->count;
1272 *buffer = rcd_buf;
1273 }
1274 return ret;
1275}
1276
1277static int
1278qeth_get_unitaddr(struct qeth_card *card)
1279{
1280 int length;
1281 char *prcd;
1282 int rc;
1283
1284 QETH_DBF_TEXT(setup, 2, "getunit");
1285 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
1286 if (rc) {
1287 PRINT_ERR("qeth_read_conf_data for device %s returned %i\n",
1288 CARD_DDEV_ID(card), rc);
1289 return rc;
1290 }
1291 card->info.chpid = prcd[30];
1292 card->info.unit_addr2 = prcd[31];
1293 card->info.cula = prcd[63];
1294 card->info.guestlan = ((prcd[0x10] == _ascebc['V']) &&
1295 (prcd[0x11] == _ascebc['M']));
1296 kfree(prcd);
1297 return 0;
1298}
1299
1300static void
1301qeth_init_tokens(struct qeth_card *card)
1302{
1303 card->token.issuer_rm_w = 0x00010103UL;
1304 card->token.cm_filter_w = 0x00010108UL;
1305 card->token.cm_connection_w = 0x0001010aUL;
1306 card->token.ulp_filter_w = 0x0001010bUL;
1307 card->token.ulp_connection_w = 0x0001010dUL;
1308}
1309
1310static inline __u16
1311raw_devno_from_bus_id(char *id)
1312{
1313 id += (strlen(id) - 4);
1314 return (__u16) simple_strtoul(id, &id, 16);
1315}
1316/**
1317 * setup channel
1318 */
1319static void
1320qeth_setup_ccw(struct qeth_channel *channel,unsigned char *iob, __u32 len)
1321{
1322 struct qeth_card *card;
1323
1324 QETH_DBF_TEXT(trace, 4, "setupccw");
1325 card = CARD_FROM_CDEV(channel->ccwdev);
1326 if (channel == &card->read)
1327 memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1));
1328 else
1329 memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1));
1330 channel->ccw.count = len;
1331 channel->ccw.cda = (__u32) __pa(iob);
1332}
1333
1334/**
1335 * get free buffer for ccws (IDX activation, lancmds,ipassists...)
1336 */
1337static struct qeth_cmd_buffer *
1338__qeth_get_buffer(struct qeth_channel *channel)
1339{
1340 __u8 index;
1341
1342 QETH_DBF_TEXT(trace, 6, "getbuff");
1343 index = channel->io_buf_no;
1344 do {
1345 if (channel->iob[index].state == BUF_STATE_FREE) {
1346 channel->iob[index].state = BUF_STATE_LOCKED;
1347 channel->io_buf_no = (channel->io_buf_no + 1) %
1348 QETH_CMD_BUFFER_NO;
1349 memset(channel->iob[index].data, 0, QETH_BUFSIZE);
1350 return channel->iob + index;
1351 }
1352 index = (index + 1) % QETH_CMD_BUFFER_NO;
1353 } while(index != channel->io_buf_no);
1354
1355 return NULL;
1356}
1357
1358/**
1359 * release command buffer
1360 */
1361static void
1362qeth_release_buffer(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
1363{
1364 unsigned long flags;
1365
1366 QETH_DBF_TEXT(trace, 6, "relbuff");
1367 spin_lock_irqsave(&channel->iob_lock, flags);
1368 memset(iob->data, 0, QETH_BUFSIZE);
1369 iob->state = BUF_STATE_FREE;
1370 iob->callback = qeth_send_control_data_cb;
1371 iob->rc = 0;
1372 spin_unlock_irqrestore(&channel->iob_lock, flags);
1373}
1374
1375static struct qeth_cmd_buffer *
1376qeth_get_buffer(struct qeth_channel *channel)
1377{
1378 struct qeth_cmd_buffer *buffer = NULL;
1379 unsigned long flags;
1380
1381 spin_lock_irqsave(&channel->iob_lock, flags);
1382 buffer = __qeth_get_buffer(channel);
1383 spin_unlock_irqrestore(&channel->iob_lock, flags);
1384 return buffer;
1385}
1386
1387static struct qeth_cmd_buffer *
1388qeth_wait_for_buffer(struct qeth_channel *channel)
1389{
1390 struct qeth_cmd_buffer *buffer;
1391 wait_event(channel->wait_q,
1392 ((buffer = qeth_get_buffer(channel)) != NULL));
1393 return buffer;
1394}
1395
1396static void
1397qeth_clear_cmd_buffers(struct qeth_channel *channel)
1398{
1399 int cnt;
1400
1401 for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++)
1402 qeth_release_buffer(channel,&channel->iob[cnt]);
1403 channel->buf_no = 0;
1404 channel->io_buf_no = 0;
1405}
1406
1407/**
1408 * start IDX for read and write channel
1409 */
1410static int
1411qeth_idx_activate_get_answer(struct qeth_channel *channel,
1412 void (*idx_reply_cb)(struct qeth_channel *,
1413 struct qeth_cmd_buffer *))
1414{
1415 struct qeth_cmd_buffer *iob;
1416 unsigned long flags;
1417 int rc;
1418 struct qeth_card *card;
1419
1420 QETH_DBF_TEXT(setup, 2, "idxanswr");
1421 card = CARD_FROM_CDEV(channel->ccwdev);
1422 iob = qeth_get_buffer(channel);
1423 iob->callback = idx_reply_cb;
1424 memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1));
1425 channel->ccw.count = QETH_BUFSIZE;
1426 channel->ccw.cda = (__u32) __pa(iob->data);
1427
1428 wait_event(card->wait_q,
1429 atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
1430 QETH_DBF_TEXT(setup, 6, "noirqpnd");
1431 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1432 rc = ccw_device_start(channel->ccwdev,
1433 &channel->ccw,(addr_t) iob, 0, 0);
1434 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1435
1436 if (rc) {
1437 PRINT_ERR("qeth: Error2 in activating channel rc=%d\n",rc);
1438 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
1439 atomic_set(&channel->irq_pending, 0);
1440 wake_up(&card->wait_q);
1441 return rc;
1442 }
1443 rc = wait_event_interruptible_timeout(card->wait_q,
1444 channel->state == CH_STATE_UP, QETH_TIMEOUT);
1445 if (rc == -ERESTARTSYS)
1446 return rc;
1447 if (channel->state != CH_STATE_UP){
1448 rc = -ETIME;
1449 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
1450 qeth_clear_cmd_buffers(channel);
1451 } else
1452 rc = 0;
1453 return rc;
1454}
1455
1456static int
1457qeth_idx_activate_channel(struct qeth_channel *channel,
1458 void (*idx_reply_cb)(struct qeth_channel *,
1459 struct qeth_cmd_buffer *))
1460{
1461 struct qeth_card *card;
1462 struct qeth_cmd_buffer *iob;
1463 unsigned long flags;
1464 __u16 temp;
1465 int rc;
1466
1467 card = CARD_FROM_CDEV(channel->ccwdev);
1468
1469 QETH_DBF_TEXT(setup, 2, "idxactch");
1470
1471 iob = qeth_get_buffer(channel);
1472 iob->callback = idx_reply_cb;
1473 memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1));
1474 channel->ccw.count = IDX_ACTIVATE_SIZE;
1475 channel->ccw.cda = (__u32) __pa(iob->data);
1476 if (channel == &card->write) {
1477 memcpy(iob->data, IDX_ACTIVATE_WRITE, IDX_ACTIVATE_SIZE);
1478 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1479 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1480 card->seqno.trans_hdr++;
1481 } else {
1482 memcpy(iob->data, IDX_ACTIVATE_READ, IDX_ACTIVATE_SIZE);
1483 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1484 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1485 }
1486 memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
1487 &card->token.issuer_rm_w,QETH_MPC_TOKEN_LENGTH);
1488 memcpy(QETH_IDX_ACT_FUNC_LEVEL(iob->data),
1489 &card->info.func_level,sizeof(__u16));
1490 temp = raw_devno_from_bus_id(CARD_DDEV_ID(card));
1491 memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &temp, 2);
1492 temp = (card->info.cula << 8) + card->info.unit_addr2;
1493 memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &temp, 2);
1494
1495 wait_event(card->wait_q,
1496 atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
1497 QETH_DBF_TEXT(setup, 6, "noirqpnd");
1498 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1499 rc = ccw_device_start(channel->ccwdev,
1500 &channel->ccw,(addr_t) iob, 0, 0);
1501 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
1502
1503 if (rc) {
1504 PRINT_ERR("qeth: Error1 in activating channel. rc=%d\n",rc);
1505 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
1506 atomic_set(&channel->irq_pending, 0);
1507 wake_up(&card->wait_q);
1508 return rc;
1509 }
1510 rc = wait_event_interruptible_timeout(card->wait_q,
1511 channel->state == CH_STATE_ACTIVATING, QETH_TIMEOUT);
1512 if (rc == -ERESTARTSYS)
1513 return rc;
1514 if (channel->state != CH_STATE_ACTIVATING) {
1515 PRINT_WARN("qeth: IDX activate timed out!\n");
1516 QETH_DBF_TEXT_(setup, 2, "2err%d", -ETIME);
1517 qeth_clear_cmd_buffers(channel);
1518 return -ETIME;
1519 }
1520 return qeth_idx_activate_get_answer(channel,idx_reply_cb);
1521}
1522
1523static int
1524qeth_peer_func_level(int level)
1525{
1526 if ((level & 0xff) == 8)
1527 return (level & 0xff) + 0x400;
1528 if (((level >> 8) & 3) == 1)
1529 return (level & 0xff) + 0x200;
1530 return level;
1531}
1532
1533static void
1534qeth_idx_write_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
1535{
1536 struct qeth_card *card;
1537 __u16 temp;
1538
1539 QETH_DBF_TEXT(setup ,2, "idxwrcb");
1540
1541 if (channel->state == CH_STATE_DOWN) {
1542 channel->state = CH_STATE_ACTIVATING;
1543 goto out;
1544 }
1545 card = CARD_FROM_CDEV(channel->ccwdev);
1546
1547 if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
1548 if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
1549 PRINT_ERR("IDX_ACTIVATE on write channel device %s: "
1550 "adapter exclusively used by another host\n",
1551 CARD_WDEV_ID(card));
1552 else
1553 PRINT_ERR("IDX_ACTIVATE on write channel device %s: "
1554 "negative reply\n", CARD_WDEV_ID(card));
1555 goto out;
1556 }
1557 memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
1558 if ((temp & ~0x0100) != qeth_peer_func_level(card->info.func_level)) {
1559 PRINT_WARN("IDX_ACTIVATE on write channel device %s: "
1560 "function level mismatch "
1561 "(sent: 0x%x, received: 0x%x)\n",
1562 CARD_WDEV_ID(card), card->info.func_level, temp);
1563 goto out;
1564 }
1565 channel->state = CH_STATE_UP;
1566out:
1567 qeth_release_buffer(channel, iob);
1568}
1569
1570static int
1571qeth_check_idx_response(unsigned char *buffer)
1572{
1573 if (!buffer)
1574 return 0;
1575
1576 QETH_DBF_HEX(control, 2, buffer, QETH_DBF_CONTROL_LEN);
1577 if ((buffer[2] & 0xc0) == 0xc0) {
1578 PRINT_WARN("received an IDX TERMINATE "
1579 "with cause code 0x%02x%s\n",
1580 buffer[4],
1581 ((buffer[4] == 0x22) ?
1582 " -- try another portname" : ""));
1583 QETH_DBF_TEXT(trace, 2, "ckidxres");
1584 QETH_DBF_TEXT(trace, 2, " idxterm");
1585 QETH_DBF_TEXT_(trace, 2, " rc%d", -EIO);
1586 return -EIO;
1587 }
1588 return 0;
1589}
1590
1591static void
1592qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
1593{
1594 struct qeth_card *card;
1595 __u16 temp;
1596
1597 QETH_DBF_TEXT(setup , 2, "idxrdcb");
1598 if (channel->state == CH_STATE_DOWN) {
1599 channel->state = CH_STATE_ACTIVATING;
1600 goto out;
1601 }
1602
1603 card = CARD_FROM_CDEV(channel->ccwdev);
1604 if (qeth_check_idx_response(iob->data)) {
1605 goto out;
1606 }
1607 if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
1608 if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
1609 PRINT_ERR("IDX_ACTIVATE on read channel device %s: "
1610 "adapter exclusively used by another host\n",
1611 CARD_RDEV_ID(card));
1612 else
1613 PRINT_ERR("IDX_ACTIVATE on read channel device %s: "
1614 "negative reply\n", CARD_RDEV_ID(card));
1615 goto out;
1616 }
1617
1618/**
1619 * temporary fix for microcode bug
1620 * to revert it,replace OR by AND
1621 */
1622 if ( (!QETH_IDX_NO_PORTNAME_REQUIRED(iob->data)) ||
1623 (card->info.type == QETH_CARD_TYPE_OSAE) )
1624 card->info.portname_required = 1;
1625
1626 memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
1627 if (temp != qeth_peer_func_level(card->info.func_level)) {
1628 PRINT_WARN("IDX_ACTIVATE on read channel device %s: function "
1629 "level mismatch (sent: 0x%x, received: 0x%x)\n",
1630 CARD_RDEV_ID(card), card->info.func_level, temp);
1631 goto out;
1632 }
1633 memcpy(&card->token.issuer_rm_r,
1634 QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
1635 QETH_MPC_TOKEN_LENGTH);
1636 memcpy(&card->info.mcl_level[0],
1637 QETH_IDX_REPLY_LEVEL(iob->data), QETH_MCL_LENGTH);
1638 channel->state = CH_STATE_UP;
1639out:
1640 qeth_release_buffer(channel,iob);
1641}
1642
1643static int
1644qeth_issue_next_read(struct qeth_card *card)
1645{
1646 int rc;
1647 struct qeth_cmd_buffer *iob;
1648
1649 QETH_DBF_TEXT(trace,5,"issnxrd");
1650 if (card->read.state != CH_STATE_UP)
1651 return -EIO;
1652 iob = qeth_get_buffer(&card->read);
1653 if (!iob) {
1654 PRINT_WARN("issue_next_read failed: no iob available!\n");
1655 return -ENOMEM;
1656 }
1657 qeth_setup_ccw(&card->read, iob->data, QETH_BUFSIZE);
1658 QETH_DBF_TEXT(trace, 6, "noirqpnd");
1659 rc = ccw_device_start(card->read.ccwdev, &card->read.ccw,
1660 (addr_t) iob, 0, 0);
1661 if (rc) {
1662 PRINT_ERR("Error in starting next read ccw! rc=%i\n", rc);
1663 atomic_set(&card->read.irq_pending, 0);
1664 qeth_schedule_recovery(card);
1665 wake_up(&card->wait_q);
1666 }
1667 return rc;
1668}
1669
1670static struct qeth_reply *
1671qeth_alloc_reply(struct qeth_card *card)
1672{
1673 struct qeth_reply *reply;
1674
1675 reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
1676 if (reply){
1677 atomic_set(&reply->refcnt, 1);
1678 atomic_set(&reply->received, 0);
1679 reply->card = card;
1680 };
1681 return reply;
1682}
1683
1684static void
1685qeth_get_reply(struct qeth_reply *reply)
1686{
1687 WARN_ON(atomic_read(&reply->refcnt) <= 0);
1688 atomic_inc(&reply->refcnt);
1689}
1690
1691static void
1692qeth_put_reply(struct qeth_reply *reply)
1693{
1694 WARN_ON(atomic_read(&reply->refcnt) <= 0);
1695 if (atomic_dec_and_test(&reply->refcnt))
1696 kfree(reply);
1697}
1698
1699static void
1700qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, struct qeth_card *card)
1701{
1702 int rc;
1703 int com;
1704 char * ipa_name;
1705
1706 com = cmd->hdr.command;
1707 rc = cmd->hdr.return_code;
1708 ipa_name = qeth_get_ipa_cmd_name(com);
1709
1710 PRINT_ERR("%s(x%X) for %s returned x%X \"%s\"\n", ipa_name, com,
1711 QETH_CARD_IFNAME(card), rc, qeth_get_ipa_msg(rc));
1712}
1713
1714static struct qeth_ipa_cmd *
1715qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
1716{
1717 struct qeth_ipa_cmd *cmd = NULL;
1718
1719 QETH_DBF_TEXT(trace,5,"chkipad");
1720 if (IS_IPA(iob->data)){
1721 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
1722 if (IS_IPA_REPLY(cmd)) {
1723 if (cmd->hdr.return_code)
1724 qeth_issue_ipa_msg(cmd, card);
1725 return cmd;
1726 }
1727 else {
1728 switch (cmd->hdr.command) {
1729 case IPA_CMD_STOPLAN:
1730 PRINT_WARN("Link failure on %s (CHPID 0x%X) - "
1731 "there is a network problem or "
1732 "someone pulled the cable or "
1733 "disabled the port.\n",
1734 QETH_CARD_IFNAME(card),
1735 card->info.chpid);
1736 card->lan_online = 0;
1737 if (card->dev && netif_carrier_ok(card->dev))
1738 netif_carrier_off(card->dev);
1739 return NULL;
1740 case IPA_CMD_STARTLAN:
1741 PRINT_INFO("Link reestablished on %s "
1742 "(CHPID 0x%X). Scheduling "
1743 "IP address reset.\n",
1744 QETH_CARD_IFNAME(card),
1745 card->info.chpid);
1746 netif_carrier_on(card->dev);
1747 qeth_schedule_recovery(card);
1748 return NULL;
1749 case IPA_CMD_MODCCID:
1750 return cmd;
1751 case IPA_CMD_REGISTER_LOCAL_ADDR:
1752 QETH_DBF_TEXT(trace,3, "irla");
1753 break;
1754 case IPA_CMD_UNREGISTER_LOCAL_ADDR:
1755 QETH_DBF_TEXT(trace,3, "urla");
1756 break;
1757 default:
1758 PRINT_WARN("Received data is IPA "
1759 "but not a reply!\n");
1760 break;
1761 }
1762 }
1763 }
1764 return cmd;
1765}
1766
1767/**
1768 * wake all waiting ipa commands
1769 */
1770static void
1771qeth_clear_ipacmd_list(struct qeth_card *card)
1772{
1773 struct qeth_reply *reply, *r;
1774 unsigned long flags;
1775
1776 QETH_DBF_TEXT(trace, 4, "clipalst");
1777
1778 spin_lock_irqsave(&card->lock, flags);
1779 list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
1780 qeth_get_reply(reply);
1781 reply->rc = -EIO;
1782 atomic_inc(&reply->received);
1783 list_del_init(&reply->list);
1784 wake_up(&reply->wait_q);
1785 qeth_put_reply(reply);
1786 }
1787 spin_unlock_irqrestore(&card->lock, flags);
1788}
1789
1790static void
1791qeth_send_control_data_cb(struct qeth_channel *channel,
1792 struct qeth_cmd_buffer *iob)
1793{
1794 struct qeth_card *card;
1795 struct qeth_reply *reply, *r;
1796 struct qeth_ipa_cmd *cmd;
1797 unsigned long flags;
1798 int keep_reply;
1799
1800 QETH_DBF_TEXT(trace,4,"sndctlcb");
1801
1802 card = CARD_FROM_CDEV(channel->ccwdev);
1803 if (qeth_check_idx_response(iob->data)) {
1804 qeth_clear_ipacmd_list(card);
1805 qeth_schedule_recovery(card);
1806 goto out;
1807 }
1808
1809 cmd = qeth_check_ipa_data(card, iob);
1810 if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
1811 goto out;
1812 /*in case of OSN : check if cmd is set */
1813 if (card->info.type == QETH_CARD_TYPE_OSN &&
1814 cmd &&
1815 cmd->hdr.command != IPA_CMD_STARTLAN &&
1816 card->osn_info.assist_cb != NULL) {
1817 card->osn_info.assist_cb(card->dev, cmd);
1818 goto out;
1819 }
1820
1821 spin_lock_irqsave(&card->lock, flags);
1822 list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
1823 if ((reply->seqno == QETH_IDX_COMMAND_SEQNO) ||
1824 ((cmd) && (reply->seqno == cmd->hdr.seqno))) {
1825 qeth_get_reply(reply);
1826 list_del_init(&reply->list);
1827 spin_unlock_irqrestore(&card->lock, flags);
1828 keep_reply = 0;
1829 if (reply->callback != NULL) {
1830 if (cmd) {
1831 reply->offset = (__u16)((char*)cmd -
1832 (char *)iob->data);
1833 keep_reply = reply->callback(card,
1834 reply,
1835 (unsigned long)cmd);
1836 } else
1837 keep_reply = reply->callback(card,
1838 reply,
1839 (unsigned long)iob);
1840 }
1841 if (cmd)
1842 reply->rc = (u16) cmd->hdr.return_code;
1843 else if (iob->rc)
1844 reply->rc = iob->rc;
1845 if (keep_reply) {
1846 spin_lock_irqsave(&card->lock, flags);
1847 list_add_tail(&reply->list,
1848 &card->cmd_waiter_list);
1849 spin_unlock_irqrestore(&card->lock, flags);
1850 } else {
1851 atomic_inc(&reply->received);
1852 wake_up(&reply->wait_q);
1853 }
1854 qeth_put_reply(reply);
1855 goto out;
1856 }
1857 }
1858 spin_unlock_irqrestore(&card->lock, flags);
1859out:
1860 memcpy(&card->seqno.pdu_hdr_ack,
1861 QETH_PDU_HEADER_SEQ_NO(iob->data),
1862 QETH_SEQ_NO_LENGTH);
1863 qeth_release_buffer(channel,iob);
1864}
1865
1866static void
1867qeth_prepare_control_data(struct qeth_card *card, int len,
1868 struct qeth_cmd_buffer *iob)
1869{
1870 qeth_setup_ccw(&card->write,iob->data,len);
1871 iob->callback = qeth_release_buffer;
1872
1873 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1874 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1875 card->seqno.trans_hdr++;
1876 memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
1877 &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
1878 card->seqno.pdu_hdr++;
1879 memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
1880 &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
1881 QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
1882}
1883
1884static int
1885qeth_send_control_data(struct qeth_card *card, int len,
1886 struct qeth_cmd_buffer *iob,
1887 int (*reply_cb)
1888 (struct qeth_card *, struct qeth_reply*, unsigned long),
1889 void *reply_param)
1890
1891{
1892 int rc;
1893 unsigned long flags;
1894 struct qeth_reply *reply = NULL;
1895 unsigned long timeout;
1896
1897 QETH_DBF_TEXT(trace, 2, "sendctl");
1898
1899 reply = qeth_alloc_reply(card);
1900 if (!reply) {
1901 PRINT_WARN("Could no alloc qeth_reply!\n");
1902 return -ENOMEM;
1903 }
1904 reply->callback = reply_cb;
1905 reply->param = reply_param;
1906 if (card->state == CARD_STATE_DOWN)
1907 reply->seqno = QETH_IDX_COMMAND_SEQNO;
1908 else
1909 reply->seqno = card->seqno.ipa++;
1910 init_waitqueue_head(&reply->wait_q);
1911 spin_lock_irqsave(&card->lock, flags);
1912 list_add_tail(&reply->list, &card->cmd_waiter_list);
1913 spin_unlock_irqrestore(&card->lock, flags);
1914 QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
1915
1916 while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
1917 qeth_prepare_control_data(card, len, iob);
1918
1919 if (IS_IPA(iob->data))
1920 timeout = jiffies + QETH_IPA_TIMEOUT;
1921 else
1922 timeout = jiffies + QETH_TIMEOUT;
1923
1924 QETH_DBF_TEXT(trace, 6, "noirqpnd");
1925 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
1926 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
1927 (addr_t) iob, 0, 0);
1928 spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
1929 if (rc){
1930 PRINT_WARN("qeth_send_control_data: "
1931 "ccw_device_start rc = %i\n", rc);
1932 QETH_DBF_TEXT_(trace, 2, " err%d", rc);
1933 spin_lock_irqsave(&card->lock, flags);
1934 list_del_init(&reply->list);
1935 qeth_put_reply(reply);
1936 spin_unlock_irqrestore(&card->lock, flags);
1937 qeth_release_buffer(iob->channel, iob);
1938 atomic_set(&card->write.irq_pending, 0);
1939 wake_up(&card->wait_q);
1940 return rc;
1941 }
1942 while (!atomic_read(&reply->received)) {
1943 if (time_after(jiffies, timeout)) {
1944 spin_lock_irqsave(&reply->card->lock, flags);
1945 list_del_init(&reply->list);
1946 spin_unlock_irqrestore(&reply->card->lock, flags);
1947 reply->rc = -ETIME;
1948 atomic_inc(&reply->received);
1949 wake_up(&reply->wait_q);
1950 }
1951 cpu_relax();
1952 };
1953 rc = reply->rc;
1954 qeth_put_reply(reply);
1955 return rc;
1956}
1957
1958static int
1959qeth_osn_send_control_data(struct qeth_card *card, int len,
1960 struct qeth_cmd_buffer *iob)
1961{
1962 unsigned long flags;
1963 int rc = 0;
1964
1965 QETH_DBF_TEXT(trace, 5, "osndctrd");
1966
1967 wait_event(card->wait_q,
1968 atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0);
1969 qeth_prepare_control_data(card, len, iob);
1970 QETH_DBF_TEXT(trace, 6, "osnoirqp");
1971 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
1972 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
1973 (addr_t) iob, 0, 0);
1974 spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
1975 if (rc){
1976 PRINT_WARN("qeth_osn_send_control_data: "
1977 "ccw_device_start rc = %i\n", rc);
1978 QETH_DBF_TEXT_(trace, 2, " err%d", rc);
1979 qeth_release_buffer(iob->channel, iob);
1980 atomic_set(&card->write.irq_pending, 0);
1981 wake_up(&card->wait_q);
1982 }
1983 return rc;
1984}
1985
1986static inline void
1987qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1988 char prot_type)
1989{
1990 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
1991 memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
1992 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
1993 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
1994}
1995
1996static int
1997qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1998 int data_len)
1999{
2000 u16 s1, s2;
2001
2002 QETH_DBF_TEXT(trace,4,"osndipa");
2003
2004 qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
2005 s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
2006 s2 = (u16)data_len;
2007 memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
2008 memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
2009 memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
2010 memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
2011 return qeth_osn_send_control_data(card, s1, iob);
2012}
2013
2014static int
2015qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
2016 int (*reply_cb)
2017 (struct qeth_card *,struct qeth_reply*, unsigned long),
2018 void *reply_param)
2019{
2020 int rc;
2021 char prot_type;
2022
2023 QETH_DBF_TEXT(trace,4,"sendipa");
2024
2025 if (card->options.layer2)
2026 if (card->info.type == QETH_CARD_TYPE_OSN)
2027 prot_type = QETH_PROT_OSN2;
2028 else
2029 prot_type = QETH_PROT_LAYER2;
2030 else
2031 prot_type = QETH_PROT_TCPIP;
2032 qeth_prepare_ipa_cmd(card,iob,prot_type);
2033 rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob,
2034 reply_cb, reply_param);
2035 return rc;
2036}
2037
2038
2039static int
2040qeth_cm_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
2041 unsigned long data)
2042{
2043 struct qeth_cmd_buffer *iob;
2044
2045 QETH_DBF_TEXT(setup, 2, "cmenblcb");
2046
2047 iob = (struct qeth_cmd_buffer *) data;
2048 memcpy(&card->token.cm_filter_r,
2049 QETH_CM_ENABLE_RESP_FILTER_TOKEN(iob->data),
2050 QETH_MPC_TOKEN_LENGTH);
2051 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
2052 return 0;
2053}
2054
2055static int
2056qeth_cm_enable(struct qeth_card *card)
2057{
2058 int rc;
2059 struct qeth_cmd_buffer *iob;
2060
2061 QETH_DBF_TEXT(setup,2,"cmenable");
2062
2063 iob = qeth_wait_for_buffer(&card->write);
2064 memcpy(iob->data, CM_ENABLE, CM_ENABLE_SIZE);
2065 memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(iob->data),
2066 &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
2067 memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data),
2068 &card->token.cm_filter_w, QETH_MPC_TOKEN_LENGTH);
2069
2070 rc = qeth_send_control_data(card, CM_ENABLE_SIZE, iob,
2071 qeth_cm_enable_cb, NULL);
2072 return rc;
2073}
2074
2075static int
2076qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
2077 unsigned long data)
2078{
2079
2080 struct qeth_cmd_buffer *iob;
2081
2082 QETH_DBF_TEXT(setup, 2, "cmsetpcb");
2083
2084 iob = (struct qeth_cmd_buffer *) data;
2085 memcpy(&card->token.cm_connection_r,
2086 QETH_CM_SETUP_RESP_DEST_ADDR(iob->data),
2087 QETH_MPC_TOKEN_LENGTH);
2088 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
2089 return 0;
2090}
2091
2092static int
2093qeth_cm_setup(struct qeth_card *card)
2094{
2095 int rc;
2096 struct qeth_cmd_buffer *iob;
2097
2098 QETH_DBF_TEXT(setup,2,"cmsetup");
2099
2100 iob = qeth_wait_for_buffer(&card->write);
2101 memcpy(iob->data, CM_SETUP, CM_SETUP_SIZE);
2102 memcpy(QETH_CM_SETUP_DEST_ADDR(iob->data),
2103 &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
2104 memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(iob->data),
2105 &card->token.cm_connection_w, QETH_MPC_TOKEN_LENGTH);
2106 memcpy(QETH_CM_SETUP_FILTER_TOKEN(iob->data),
2107 &card->token.cm_filter_r, QETH_MPC_TOKEN_LENGTH);
2108 rc = qeth_send_control_data(card, CM_SETUP_SIZE, iob,
2109 qeth_cm_setup_cb, NULL);
2110 return rc;
2111
2112}
2113
2114static int
2115qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
2116 unsigned long data)
2117{
2118
2119 __u16 mtu, framesize;
2120 __u16 len;
2121 __u8 link_type;
2122 struct qeth_cmd_buffer *iob;
2123
2124 QETH_DBF_TEXT(setup, 2, "ulpenacb");
2125
2126 iob = (struct qeth_cmd_buffer *) data;
2127 memcpy(&card->token.ulp_filter_r,
2128 QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data),
2129 QETH_MPC_TOKEN_LENGTH);
2130 if (qeth_get_mtu_out_of_mpc(card->info.type)) {
2131 memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2);
2132 mtu = qeth_get_mtu_outof_framesize(framesize);
2133 if (!mtu) {
2134 iob->rc = -EINVAL;
2135 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
2136 return 0;
2137 }
2138 card->info.max_mtu = mtu;
2139 card->info.initial_mtu = mtu;
2140 card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE;
2141 } else {
2142 card->info.initial_mtu = qeth_get_initial_mtu_for_card(card);
2143 card->info.max_mtu = qeth_get_max_mtu_for_card(card->info.type);
2144 card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
2145 }
2146
2147 memcpy(&len, QETH_ULP_ENABLE_RESP_DIFINFO_LEN(iob->data), 2);
2148 if (len >= QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
2149 memcpy(&link_type,
2150 QETH_ULP_ENABLE_RESP_LINK_TYPE(iob->data), 1);
2151 card->info.link_type = link_type;
2152 } else
2153 card->info.link_type = 0;
2154 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
2155 return 0;
2156}
2157
2158static int
2159qeth_ulp_enable(struct qeth_card *card)
2160{
2161 int rc;
2162 char prot_type;
2163 struct qeth_cmd_buffer *iob;
2164
2165 /*FIXME: trace view callbacks*/
2166 QETH_DBF_TEXT(setup,2,"ulpenabl");
2167
2168 iob = qeth_wait_for_buffer(&card->write);
2169 memcpy(iob->data, ULP_ENABLE, ULP_ENABLE_SIZE);
2170
2171 *(QETH_ULP_ENABLE_LINKNUM(iob->data)) =
2172 (__u8) card->info.portno;
2173 if (card->options.layer2)
2174 if (card->info.type == QETH_CARD_TYPE_OSN)
2175 prot_type = QETH_PROT_OSN2;
2176 else
2177 prot_type = QETH_PROT_LAYER2;
2178 else
2179 prot_type = QETH_PROT_TCPIP;
2180
2181 memcpy(QETH_ULP_ENABLE_PROT_TYPE(iob->data),&prot_type,1);
2182 memcpy(QETH_ULP_ENABLE_DEST_ADDR(iob->data),
2183 &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
2184 memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data),
2185 &card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH);
2186 memcpy(QETH_ULP_ENABLE_PORTNAME_AND_LL(iob->data),
2187 card->info.portname, 9);
2188 rc = qeth_send_control_data(card, ULP_ENABLE_SIZE, iob,
2189 qeth_ulp_enable_cb, NULL);
2190 return rc;
2191
2192}
2193
2194static int
2195qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
2196 unsigned long data)
2197{
2198 struct qeth_cmd_buffer *iob;
2199
2200 QETH_DBF_TEXT(setup, 2, "ulpstpcb");
2201
2202 iob = (struct qeth_cmd_buffer *) data;
2203 memcpy(&card->token.ulp_connection_r,
2204 QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data),
2205 QETH_MPC_TOKEN_LENGTH);
2206 QETH_DBF_TEXT_(setup, 2, " rc%d", iob->rc);
2207 return 0;
2208}
2209
2210static int
2211qeth_ulp_setup(struct qeth_card *card)
2212{
2213 int rc;
2214 __u16 temp;
2215 struct qeth_cmd_buffer *iob;
2216 struct ccw_dev_id dev_id;
2217
2218 QETH_DBF_TEXT(setup,2,"ulpsetup");
2219
2220 iob = qeth_wait_for_buffer(&card->write);
2221 memcpy(iob->data, ULP_SETUP, ULP_SETUP_SIZE);
2222
2223 memcpy(QETH_ULP_SETUP_DEST_ADDR(iob->data),
2224 &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
2225 memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(iob->data),
2226 &card->token.ulp_connection_w, QETH_MPC_TOKEN_LENGTH);
2227 memcpy(QETH_ULP_SETUP_FILTER_TOKEN(iob->data),
2228 &card->token.ulp_filter_r, QETH_MPC_TOKEN_LENGTH);
2229
2230 ccw_device_get_id(CARD_DDEV(card), &dev_id);
2231 memcpy(QETH_ULP_SETUP_CUA(iob->data), &dev_id.devno, 2);
2232 temp = (card->info.cula << 8) + card->info.unit_addr2;
2233 memcpy(QETH_ULP_SETUP_REAL_DEVADDR(iob->data), &temp, 2);
2234 rc = qeth_send_control_data(card, ULP_SETUP_SIZE, iob,
2235 qeth_ulp_setup_cb, NULL);
2236 return rc;
2237}
2238
2239static inline int
2240qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
2241 unsigned int siga_error, const char *dbftext)
2242{
2243 if (qdio_error || siga_error) {
2244 QETH_DBF_TEXT(trace, 2, dbftext);
2245 QETH_DBF_TEXT(qerr, 2, dbftext);
2246 QETH_DBF_TEXT_(qerr, 2, " F15=%02X",
2247 buf->element[15].flags & 0xff);
2248 QETH_DBF_TEXT_(qerr, 2, " F14=%02X",
2249 buf->element[14].flags & 0xff);
2250 QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error);
2251 QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error);
2252 return 1;
2253 }
2254 return 0;
2255}
2256
2257static struct sk_buff *
2258qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
2259{
2260 struct sk_buff* skb;
2261 int add_len;
2262
2263 add_len = 0;
2264 if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN)
2265 add_len = sizeof(struct qeth_hdr);
2266#ifdef CONFIG_QETH_VLAN
2267 else
2268 add_len = VLAN_HLEN;
2269#endif
2270 skb = dev_alloc_skb(length + add_len);
2271 if (skb && add_len)
2272 skb_reserve(skb, add_len);
2273 return skb;
2274}
2275
2276static inline int
2277qeth_create_skb_frag(struct qdio_buffer_element *element,
2278 struct sk_buff **pskb,
2279 int offset, int *pfrag, int data_len)
2280{
2281 struct page *page = virt_to_page(element->addr);
2282 if (*pfrag == 0) {
2283 /* the upper protocol layers assume that there is data in the
2284 * skb itself. Copy a small amount (64 bytes) to make them
2285 * happy. */
2286 *pskb = dev_alloc_skb(64 + QETH_FAKE_LL_LEN_ETH);
2287 if (!(*pskb))
2288 return -ENOMEM;
2289 skb_reserve(*pskb, QETH_FAKE_LL_LEN_ETH);
2290 if (data_len <= 64) {
2291 memcpy(skb_put(*pskb, data_len), element->addr + offset,
2292 data_len);
2293 } else {
2294 get_page(page);
2295 memcpy(skb_put(*pskb, 64), element->addr + offset, 64);
2296 skb_fill_page_desc(*pskb, *pfrag, page, offset + 64,
2297 data_len - 64);
2298 (*pskb)->data_len += data_len - 64;
2299 (*pskb)->len += data_len - 64;
2300 (*pskb)->truesize += data_len - 64;
2301 }
2302 } else {
2303 get_page(page);
2304 skb_fill_page_desc(*pskb, *pfrag, page, offset, data_len);
2305 (*pskb)->data_len += data_len;
2306 (*pskb)->len += data_len;
2307 (*pskb)->truesize += data_len;
2308 }
2309 (*pfrag)++;
2310 return 0;
2311}
2312
2313static inline struct qeth_buffer_pool_entry *
2314qeth_find_free_buffer_pool_entry(struct qeth_card *card)
2315{
2316 struct list_head *plh;
2317 struct qeth_buffer_pool_entry *entry;
2318 int i, free;
2319 struct page *page;
2320
2321 if (list_empty(&card->qdio.in_buf_pool.entry_list))
2322 return NULL;
2323
2324 list_for_each(plh, &card->qdio.in_buf_pool.entry_list) {
2325 entry = list_entry(plh, struct qeth_buffer_pool_entry, list);
2326 free = 1;
2327 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
2328 if (page_count(virt_to_page(entry->elements[i])) > 1) {
2329 free = 0;
2330 break;
2331 }
2332 }
2333 if (free) {
2334 list_del_init(&entry->list);
2335 return entry;
2336 }
2337 }
2338
2339 /* no free buffer in pool so take first one and swap pages */
2340 entry = list_entry(card->qdio.in_buf_pool.entry_list.next,
2341 struct qeth_buffer_pool_entry, list);
2342 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
2343 if (page_count(virt_to_page(entry->elements[i])) > 1) {
2344 page = alloc_page(GFP_ATOMIC|GFP_DMA);
2345 if (!page) {
2346 return NULL;
2347 } else {
2348 free_page((unsigned long)entry->elements[i]);
2349 entry->elements[i] = page_address(page);
2350 if (card->options.performance_stats)
2351 card->perf_stats.sg_alloc_page_rx++;
2352 }
2353 }
2354 }
2355 list_del_init(&entry->list);
2356 return entry;
2357}
2358
2359static struct sk_buff *
2360qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2361 struct qdio_buffer_element **__element, int *__offset,
2362 struct qeth_hdr **hdr)
2363{
2364 struct qdio_buffer_element *element = *__element;
2365 int offset = *__offset;
2366 struct sk_buff *skb = NULL;
2367 int skb_len;
2368 void *data_ptr;
2369 int data_len;
2370 int use_rx_sg = 0;
2371 int frag = 0;
2372
2373 QETH_DBF_TEXT(trace,6,"nextskb");
2374 /* qeth_hdr must not cross element boundaries */
2375 if (element->length < offset + sizeof(struct qeth_hdr)){
2376 if (qeth_is_last_sbale(element))
2377 return NULL;
2378 element++;
2379 offset = 0;
2380 if (element->length < sizeof(struct qeth_hdr))
2381 return NULL;
2382 }
2383 *hdr = element->addr + offset;
2384
2385 offset += sizeof(struct qeth_hdr);
2386 if (card->options.layer2)
2387 if (card->info.type == QETH_CARD_TYPE_OSN)
2388 skb_len = (*hdr)->hdr.osn.pdu_length;
2389 else
2390 skb_len = (*hdr)->hdr.l2.pkt_length;
2391 else
2392 skb_len = (*hdr)->hdr.l3.length;
2393
2394 if (!skb_len)
2395 return NULL;
2396 if ((skb_len >= card->options.rx_sg_cb) &&
2397 (!(card->info.type == QETH_CARD_TYPE_OSN)) &&
2398 (!atomic_read(&card->force_alloc_skb))) {
2399 use_rx_sg = 1;
2400 } else {
2401 if (card->options.fake_ll) {
2402 if (card->dev->type == ARPHRD_IEEE802_TR) {
2403 if (!(skb = qeth_get_skb(skb_len +
2404 QETH_FAKE_LL_LEN_TR, *hdr)))
2405 goto no_mem;
2406 skb_reserve(skb, QETH_FAKE_LL_LEN_TR);
2407 } else {
2408 if (!(skb = qeth_get_skb(skb_len +
2409 QETH_FAKE_LL_LEN_ETH, *hdr)))
2410 goto no_mem;
2411 skb_reserve(skb, QETH_FAKE_LL_LEN_ETH);
2412 }
2413 } else {
2414 skb = qeth_get_skb(skb_len, *hdr);
2415 if (!skb)
2416 goto no_mem;
2417 }
2418 }
2419
2420 data_ptr = element->addr + offset;
2421 while (skb_len) {
2422 data_len = min(skb_len, (int)(element->length - offset));
2423 if (data_len) {
2424 if (use_rx_sg) {
2425 if (qeth_create_skb_frag(element, &skb, offset,
2426 &frag, data_len))
2427 goto no_mem;
2428 } else {
2429 memcpy(skb_put(skb, data_len), data_ptr,
2430 data_len);
2431 }
2432 }
2433 skb_len -= data_len;
2434 if (skb_len){
2435 if (qeth_is_last_sbale(element)){
2436 QETH_DBF_TEXT(trace,4,"unexeob");
2437 QETH_DBF_TEXT_(trace,4,"%s",CARD_BUS_ID(card));
2438 QETH_DBF_TEXT(qerr,2,"unexeob");
2439 QETH_DBF_TEXT_(qerr,2,"%s",CARD_BUS_ID(card));
2440 QETH_DBF_HEX(misc,4,buffer,sizeof(*buffer));
2441 dev_kfree_skb_any(skb);
2442 card->stats.rx_errors++;
2443 return NULL;
2444 }
2445 element++;
2446 offset = 0;
2447 data_ptr = element->addr;
2448 } else {
2449 offset += data_len;
2450 }
2451 }
2452 *__element = element;
2453 *__offset = offset;
2454 if (use_rx_sg && card->options.performance_stats) {
2455 card->perf_stats.sg_skbs_rx++;
2456 card->perf_stats.sg_frags_rx += skb_shinfo(skb)->nr_frags;
2457 }
2458 return skb;
2459no_mem:
2460 if (net_ratelimit()){
2461 PRINT_WARN("No memory for packet received on %s.\n",
2462 QETH_CARD_IFNAME(card));
2463 QETH_DBF_TEXT(trace,2,"noskbmem");
2464 QETH_DBF_TEXT_(trace,2,"%s",CARD_BUS_ID(card));
2465 }
2466 card->stats.rx_dropped++;
2467 return NULL;
2468}
2469
2470static __be16
2471qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
2472{
2473 struct qeth_card *card;
2474 struct ethhdr *eth;
2475
2476 QETH_DBF_TEXT(trace,6,"typtrans");
2477
2478 card = (struct qeth_card *)dev->priv;
2479#ifdef CONFIG_TR
2480 if ((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
2481 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))
2482 return tr_type_trans(skb,dev);
2483#endif /* CONFIG_TR */
2484 skb_reset_mac_header(skb);
2485 skb_pull(skb, ETH_HLEN );
2486 eth = eth_hdr(skb);
2487
2488 if (*eth->h_dest & 1) {
2489 if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0)
2490 skb->pkt_type = PACKET_BROADCAST;
2491 else
2492 skb->pkt_type = PACKET_MULTICAST;
2493 } else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
2494 skb->pkt_type = PACKET_OTHERHOST;
2495
2496 if (ntohs(eth->h_proto) >= 1536)
2497 return eth->h_proto;
2498 if (*(unsigned short *) (skb->data) == 0xFFFF)
2499 return htons(ETH_P_802_3);
2500 return htons(ETH_P_802_2);
2501}
2502
2503static void
2504qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
2505 struct qeth_hdr *hdr)
2506{
2507 struct trh_hdr *fake_hdr;
2508 struct trllc *fake_llc;
2509 struct iphdr *ip_hdr;
2510
2511 QETH_DBF_TEXT(trace,5,"skbfktr");
2512 skb_set_mac_header(skb, (int)-QETH_FAKE_LL_LEN_TR);
2513 /* this is a fake ethernet header */
2514 fake_hdr = tr_hdr(skb);
2515
2516 /* the destination MAC address */
2517 switch (skb->pkt_type){
2518 case PACKET_MULTICAST:
2519 switch (skb->protocol){
2520#ifdef CONFIG_QETH_IPV6
2521 case __constant_htons(ETH_P_IPV6):
2522 ndisc_mc_map((struct in6_addr *)
2523 skb->data + QETH_FAKE_LL_V6_ADDR_POS,
2524 fake_hdr->daddr, card->dev, 0);
2525 break;
2526#endif /* CONFIG_QETH_IPV6 */
2527 case __constant_htons(ETH_P_IP):
2528 ip_hdr = (struct iphdr *)skb->data;
2529 ip_tr_mc_map(ip_hdr->daddr, fake_hdr->daddr);
2530 break;
2531 default:
2532 memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
2533 }
2534 break;
2535 case PACKET_BROADCAST:
2536 memset(fake_hdr->daddr, 0xff, TR_ALEN);
2537 break;
2538 default:
2539 memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
2540 }
2541 /* the source MAC address */
2542 if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
2543 memcpy(fake_hdr->saddr, &hdr->hdr.l3.dest_addr[2], TR_ALEN);
2544 else
2545 memset(fake_hdr->saddr, 0, TR_ALEN);
2546 fake_hdr->rcf=0;
2547 fake_llc = (struct trllc*)&(fake_hdr->rcf);
2548 fake_llc->dsap = EXTENDED_SAP;
2549 fake_llc->ssap = EXTENDED_SAP;
2550 fake_llc->llc = UI_CMD;
2551 fake_llc->protid[0] = 0;
2552 fake_llc->protid[1] = 0;
2553 fake_llc->protid[2] = 0;
2554 fake_llc->ethertype = ETH_P_IP;
2555}
2556
2557static void
2558qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb,
2559 struct qeth_hdr *hdr)
2560{
2561 struct ethhdr *fake_hdr;
2562 struct iphdr *ip_hdr;
2563
2564 QETH_DBF_TEXT(trace,5,"skbfketh");
2565 skb_set_mac_header(skb, -QETH_FAKE_LL_LEN_ETH);
2566 /* this is a fake ethernet header */
2567 fake_hdr = eth_hdr(skb);
2568
2569 /* the destination MAC address */
2570 switch (skb->pkt_type){
2571 case PACKET_MULTICAST:
2572 switch (skb->protocol){
2573#ifdef CONFIG_QETH_IPV6
2574 case __constant_htons(ETH_P_IPV6):
2575 ndisc_mc_map((struct in6_addr *)
2576 skb->data + QETH_FAKE_LL_V6_ADDR_POS,
2577 fake_hdr->h_dest, card->dev, 0);
2578 break;
2579#endif /* CONFIG_QETH_IPV6 */
2580 case __constant_htons(ETH_P_IP):
2581 ip_hdr = (struct iphdr *)skb->data;
2582 ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
2583 break;
2584 default:
2585 memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN);
2586 }
2587 break;
2588 case PACKET_BROADCAST:
2589 memset(fake_hdr->h_dest, 0xff, ETH_ALEN);
2590 break;
2591 default:
2592 memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN);
2593 }
2594 /* the source MAC address */
2595 if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
2596 memcpy(fake_hdr->h_source, &hdr->hdr.l3.dest_addr[2], ETH_ALEN);
2597 else
2598 memset(fake_hdr->h_source, 0, ETH_ALEN);
2599 /* the protocol */
2600 fake_hdr->h_proto = skb->protocol;
2601}
2602
2603static inline void
2604qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
2605 struct qeth_hdr *hdr)
2606{
2607 if (card->dev->type == ARPHRD_IEEE802_TR)
2608 qeth_rebuild_skb_fake_ll_tr(card, skb, hdr);
2609 else
2610 qeth_rebuild_skb_fake_ll_eth(card, skb, hdr);
2611}
2612
2613static inline void
2614qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
2615 struct qeth_hdr *hdr)
2616{
2617 skb->pkt_type = PACKET_HOST;
2618 skb->protocol = qeth_type_trans(skb, skb->dev);
2619 if (card->options.checksum_type == NO_CHECKSUMMING)
2620 skb->ip_summed = CHECKSUM_UNNECESSARY;
2621 else
2622 skb->ip_summed = CHECKSUM_NONE;
2623 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
2624}
2625
2626static __u16
2627qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
2628 struct qeth_hdr *hdr)
2629{
2630 unsigned short vlan_id = 0;
2631#ifdef CONFIG_QETH_IPV6
2632 if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) {
2633 skb->pkt_type = PACKET_HOST;
2634 skb->protocol = qeth_type_trans(skb, card->dev);
2635 return 0;
2636 }
2637#endif /* CONFIG_QETH_IPV6 */
2638 skb->protocol = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 :
2639 ETH_P_IP);
2640 switch (hdr->hdr.l3.flags & QETH_HDR_CAST_MASK){
2641 case QETH_CAST_UNICAST:
2642 skb->pkt_type = PACKET_HOST;
2643 break;
2644 case QETH_CAST_MULTICAST:
2645 skb->pkt_type = PACKET_MULTICAST;
2646 card->stats.multicast++;
2647 break;
2648 case QETH_CAST_BROADCAST:
2649 skb->pkt_type = PACKET_BROADCAST;
2650 card->stats.multicast++;
2651 break;
2652 case QETH_CAST_ANYCAST:
2653 case QETH_CAST_NOCAST:
2654 default:
2655 skb->pkt_type = PACKET_HOST;
2656 }
2657
2658 if (hdr->hdr.l3.ext_flags &
2659 (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
2660 vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
2661 hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
2662 }
2663
2664 if (card->options.fake_ll)
2665 qeth_rebuild_skb_fake_ll(card, skb, hdr);
2666 else
2667 skb_reset_mac_header(skb);
2668 skb->ip_summed = card->options.checksum_type;
2669 if (card->options.checksum_type == HW_CHECKSUMMING){
2670 if ( (hdr->hdr.l3.ext_flags &
2671 (QETH_HDR_EXT_CSUM_HDR_REQ |
2672 QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
2673 (QETH_HDR_EXT_CSUM_HDR_REQ |
2674 QETH_HDR_EXT_CSUM_TRANSP_REQ) )
2675 skb->ip_summed = CHECKSUM_UNNECESSARY;
2676 else
2677 skb->ip_summed = SW_CHECKSUMMING;
2678 }
2679 return vlan_id;
2680}
2681
2682static void
2683qeth_process_inbound_buffer(struct qeth_card *card,
2684 struct qeth_qdio_buffer *buf, int index)
2685{
2686 struct qdio_buffer_element *element;
2687 struct sk_buff *skb;
2688 struct qeth_hdr *hdr;
2689 int offset;
2690 int rxrc;
2691 __u16 vlan_tag = 0;
2692
2693 /* get first element of current buffer */
2694 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
2695 offset = 0;
2696 if (card->options.performance_stats)
2697 card->perf_stats.bufs_rec++;
2698 while((skb = qeth_get_next_skb(card, buf->buffer, &element,
2699 &offset, &hdr))) {
2700 skb->dev = card->dev;
2701 if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
2702 qeth_layer2_rebuild_skb(card, skb, hdr);
2703 else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
2704 vlan_tag = qeth_rebuild_skb(card, skb, hdr);
2705 else if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN) {
2706 skb_push(skb, sizeof(struct qeth_hdr));
2707 skb_copy_to_linear_data(skb, hdr,
2708 sizeof(struct qeth_hdr));
2709 } else { /* unknown header type */
2710 dev_kfree_skb_any(skb);
2711 QETH_DBF_TEXT(trace, 3, "inbunkno");
2712 QETH_DBF_HEX(control, 3, hdr, QETH_DBF_CONTROL_LEN);
2713 continue;
2714 }
2715 /* is device UP ? */
2716 if (!(card->dev->flags & IFF_UP)){
2717 dev_kfree_skb_any(skb);
2718 continue;
2719 }
2720 if (card->info.type == QETH_CARD_TYPE_OSN)
2721 rxrc = card->osn_info.data_cb(skb);
2722 else
2723#ifdef CONFIG_QETH_VLAN
2724 if (vlan_tag)
2725 if (card->vlangrp)
2726 vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
2727 else {
2728 dev_kfree_skb_any(skb);
2729 continue;
2730 }
2731 else
2732#endif
2733 rxrc = netif_rx(skb);
2734 card->dev->last_rx = jiffies;
2735 card->stats.rx_packets++;
2736 card->stats.rx_bytes += skb->len;
2737 }
2738}
2739
2740static int
2741qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
2742{
2743 struct qeth_buffer_pool_entry *pool_entry;
2744 int i;
2745
2746 pool_entry = qeth_find_free_buffer_pool_entry(card);
2747 if (!pool_entry)
2748 return 1;
2749 /*
2750 * since the buffer is accessed only from the input_tasklet
2751 * there shouldn't be a need to synchronize; also, since we use
2752 * the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run out off
2753 * buffers
2754 */
2755 BUG_ON(!pool_entry);
2756
2757 buf->pool_entry = pool_entry;
2758 for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){
2759 buf->buffer->element[i].length = PAGE_SIZE;
2760 buf->buffer->element[i].addr = pool_entry->elements[i];
2761 if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
2762 buf->buffer->element[i].flags = SBAL_FLAGS_LAST_ENTRY;
2763 else
2764 buf->buffer->element[i].flags = 0;
2765 }
2766 buf->state = QETH_QDIO_BUF_EMPTY;
2767 return 0;
2768}
2769
2770static void
2771qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
2772 struct qeth_qdio_out_buffer *buf)
2773{
2774 int i;
2775 struct sk_buff *skb;
2776
2777 /* is PCI flag set on buffer? */
2778 if (buf->buffer->element[0].flags & 0x40)
2779 atomic_dec(&queue->set_pci_flags_count);
2780
2781 while ((skb = skb_dequeue(&buf->skb_list))){
2782 atomic_dec(&skb->users);
2783 dev_kfree_skb_any(skb);
2784 }
2785 qeth_eddp_buf_release_contexts(buf);
2786 for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i){
2787 buf->buffer->element[i].length = 0;
2788 buf->buffer->element[i].addr = NULL;
2789 buf->buffer->element[i].flags = 0;
2790 }
2791 buf->next_element_to_fill = 0;
2792 atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
2793}
2794
2795static void
2796qeth_queue_input_buffer(struct qeth_card *card, int index)
2797{
2798 struct qeth_qdio_q *queue = card->qdio.in_q;
2799 int count;
2800 int i;
2801 int rc;
2802 int newcount = 0;
2803
2804 QETH_DBF_TEXT(trace,6,"queinbuf");
2805 count = (index < queue->next_buf_to_init)?
2806 card->qdio.in_buf_pool.buf_count -
2807 (queue->next_buf_to_init - index) :
2808 card->qdio.in_buf_pool.buf_count -
2809 (queue->next_buf_to_init + QDIO_MAX_BUFFERS_PER_Q - index);
2810 /* only requeue at a certain threshold to avoid SIGAs */
2811 if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)){
2812 for (i = queue->next_buf_to_init;
2813 i < queue->next_buf_to_init + count; ++i) {
2814 if (qeth_init_input_buffer(card,
2815 &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q])) {
2816 break;
2817 } else {
2818 newcount++;
2819 }
2820 }
2821
2822 if (newcount < count) {
2823 /* we are in memory shortage so we switch back to
2824 traditional skb allocation and drop packages */
2825 if (!atomic_read(&card->force_alloc_skb) &&
2826 net_ratelimit())
2827 PRINT_WARN("Switch to alloc skb\n");
2828 atomic_set(&card->force_alloc_skb, 3);
2829 count = newcount;
2830 } else {
2831 if ((atomic_read(&card->force_alloc_skb) == 1) &&
2832 net_ratelimit())
2833 PRINT_WARN("Switch to sg\n");
2834 atomic_add_unless(&card->force_alloc_skb, -1, 0);
2835 }
2836
2837 /*
2838 * according to old code it should be avoided to requeue all
2839 * 128 buffers in order to benefit from PCI avoidance.
2840 * this function keeps at least one buffer (the buffer at
2841 * 'index') un-requeued -> this buffer is the first buffer that
2842 * will be requeued the next time
2843 */
2844 if (card->options.performance_stats) {
2845 card->perf_stats.inbound_do_qdio_cnt++;
2846 card->perf_stats.inbound_do_qdio_start_time =
2847 qeth_get_micros();
2848 }
2849 rc = do_QDIO(CARD_DDEV(card),
2850 QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT,
2851 0, queue->next_buf_to_init, count, NULL);
2852 if (card->options.performance_stats)
2853 card->perf_stats.inbound_do_qdio_time +=
2854 qeth_get_micros() -
2855 card->perf_stats.inbound_do_qdio_start_time;
2856 if (rc){
2857 PRINT_WARN("qeth_queue_input_buffer's do_QDIO "
2858 "return %i (device %s).\n",
2859 rc, CARD_DDEV_ID(card));
2860 QETH_DBF_TEXT(trace,2,"qinberr");
2861 QETH_DBF_TEXT_(trace,2,"%s",CARD_BUS_ID(card));
2862 }
2863 queue->next_buf_to_init = (queue->next_buf_to_init + count) %
2864 QDIO_MAX_BUFFERS_PER_Q;
2865 }
2866}
2867
2868static inline void
2869qeth_put_buffer_pool_entry(struct qeth_card *card,
2870 struct qeth_buffer_pool_entry *entry)
2871{
2872 QETH_DBF_TEXT(trace, 6, "ptbfplen");
2873 list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
2874}
2875
2876static void
2877qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
2878 unsigned int qdio_err, unsigned int siga_err,
2879 unsigned int queue, int first_element, int count,
2880 unsigned long card_ptr)
2881{
2882 struct net_device *net_dev;
2883 struct qeth_card *card;
2884 struct qeth_qdio_buffer *buffer;
2885 int index;
2886 int i;
2887
2888 QETH_DBF_TEXT(trace, 6, "qdinput");
2889 card = (struct qeth_card *) card_ptr;
2890 net_dev = card->dev;
2891 if (card->options.performance_stats) {
2892 card->perf_stats.inbound_cnt++;
2893 card->perf_stats.inbound_start_time = qeth_get_micros();
2894 }
2895 if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
2896 if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
2897 QETH_DBF_TEXT(trace, 1,"qdinchk");
2898 QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
2899 QETH_DBF_TEXT_(trace,1,"%04X%04X",first_element,count);
2900 QETH_DBF_TEXT_(trace,1,"%04X%04X", queue, status);
2901 qeth_schedule_recovery(card);
2902 return;
2903 }
2904 }
2905 for (i = first_element; i < (first_element + count); ++i) {
2906 index = i % QDIO_MAX_BUFFERS_PER_Q;
2907 buffer = &card->qdio.in_q->bufs[index];
2908 if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
2909 qeth_check_qdio_errors(buffer->buffer,
2910 qdio_err, siga_err,"qinerr")))
2911 qeth_process_inbound_buffer(card, buffer, index);
2912 /* clear buffer and give back to hardware */
2913 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
2914 qeth_queue_input_buffer(card, index);
2915 }
2916 if (card->options.performance_stats)
2917 card->perf_stats.inbound_time += qeth_get_micros() -
2918 card->perf_stats.inbound_start_time;
2919}
2920
2921static int
2922qeth_handle_send_error(struct qeth_card *card,
2923 struct qeth_qdio_out_buffer *buffer,
2924 unsigned int qdio_err, unsigned int siga_err)
2925{
2926 int sbalf15 = buffer->buffer->element[15].flags & 0xff;
2927 int cc = siga_err & 3;
2928
2929 QETH_DBF_TEXT(trace, 6, "hdsnderr");
2930 qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr");
2931 switch (cc) {
2932 case 0:
2933 if (qdio_err){
2934 QETH_DBF_TEXT(trace, 1,"lnkfail");
2935 QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
2936 QETH_DBF_TEXT_(trace,1,"%04x %02x",
2937 (u16)qdio_err, (u8)sbalf15);
2938 return QETH_SEND_ERROR_LINK_FAILURE;
2939 }
2940 return QETH_SEND_ERROR_NONE;
2941 case 2:
2942 if (siga_err & QDIO_SIGA_ERROR_B_BIT_SET) {
2943 QETH_DBF_TEXT(trace, 1, "SIGAcc2B");
2944 QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
2945 return QETH_SEND_ERROR_KICK_IT;
2946 }
2947 if ((sbalf15 >= 15) && (sbalf15 <= 31))
2948 return QETH_SEND_ERROR_RETRY;
2949 return QETH_SEND_ERROR_LINK_FAILURE;
2950 /* look at qdio_error and sbalf 15 */
2951 case 1:
2952 QETH_DBF_TEXT(trace, 1, "SIGAcc1");
2953 QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
2954 return QETH_SEND_ERROR_LINK_FAILURE;
2955 case 3:
2956 default:
2957 QETH_DBF_TEXT(trace, 1, "SIGAcc3");
2958 QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
2959 return QETH_SEND_ERROR_KICK_IT;
2960 }
2961}
2962
2963void
2964qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
2965 int index, int count)
2966{
2967 struct qeth_qdio_out_buffer *buf;
2968 int rc;
2969 int i;
2970 unsigned int qdio_flags;
2971
2972 QETH_DBF_TEXT(trace, 6, "flushbuf");
2973
2974 for (i = index; i < index + count; ++i) {
2975 buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
2976 buf->buffer->element[buf->next_element_to_fill - 1].flags |=
2977 SBAL_FLAGS_LAST_ENTRY;
2978
2979 if (queue->card->info.type == QETH_CARD_TYPE_IQD)
2980 continue;
2981
2982 if (!queue->do_pack){
2983 if ((atomic_read(&queue->used_buffers) >=
2984 (QETH_HIGH_WATERMARK_PACK -
2985 QETH_WATERMARK_PACK_FUZZ)) &&
2986 !atomic_read(&queue->set_pci_flags_count)){
2987 /* it's likely that we'll go to packing
2988 * mode soon */
2989 atomic_inc(&queue->set_pci_flags_count);
2990 buf->buffer->element[0].flags |= 0x40;
2991 }
2992 } else {
2993 if (!atomic_read(&queue->set_pci_flags_count)){
2994 /*
2995 * there's no outstanding PCI any more, so we
2996 * have to request a PCI to be sure that the PCI
2997 * will wake at some time in the future then we
2998 * can flush packed buffers that might still be
2999 * hanging around, which can happen if no
3000 * further send was requested by the stack
3001 */
3002 atomic_inc(&queue->set_pci_flags_count);
3003 buf->buffer->element[0].flags |= 0x40;
3004 }
3005 }
3006 }
3007
3008 queue->card->dev->trans_start = jiffies;
3009 if (queue->card->options.performance_stats) {
3010 queue->card->perf_stats.outbound_do_qdio_cnt++;
3011 queue->card->perf_stats.outbound_do_qdio_start_time =
3012 qeth_get_micros();
3013 }
3014 qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
3015 if (under_int)
3016 qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT;
3017 if (atomic_read(&queue->set_pci_flags_count))
3018 qdio_flags |= QDIO_FLAG_PCI_OUT;
3019 rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
3020 queue->queue_no, index, count, NULL);
3021 if (queue->card->options.performance_stats)
3022 queue->card->perf_stats.outbound_do_qdio_time +=
3023 qeth_get_micros() -
3024 queue->card->perf_stats.outbound_do_qdio_start_time;
3025 if (rc){
3026 QETH_DBF_TEXT(trace, 2, "flushbuf");
3027 QETH_DBF_TEXT_(trace, 2, " err%d", rc);
3028 QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card));
3029 queue->card->stats.tx_errors += count;
3030 /* this must not happen under normal circumstances. if it
3031 * happens something is really wrong -> recover */
3032 qeth_schedule_recovery(queue->card);
3033 return;
3034 }
3035 atomic_add(count, &queue->used_buffers);
3036 if (queue->card->options.performance_stats)
3037 queue->card->perf_stats.bufs_sent += count;
3038}
3039
3040/*
3041 * Switched to packing state if the number of used buffers on a queue
3042 * reaches a certain limit.
3043 */
3044static void
3045qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
3046{
3047 if (!queue->do_pack) {
3048 if (atomic_read(&queue->used_buffers)
3049 >= QETH_HIGH_WATERMARK_PACK){
3050 /* switch non-PACKING -> PACKING */
3051 QETH_DBF_TEXT(trace, 6, "np->pack");
3052 if (queue->card->options.performance_stats)
3053 queue->card->perf_stats.sc_dp_p++;
3054 queue->do_pack = 1;
3055 }
3056 }
3057}
3058
3059/*
3060 * Switches from packing to non-packing mode. If there is a packing
3061 * buffer on the queue this buffer will be prepared to be flushed.
3062 * In that case 1 is returned to inform the caller. If no buffer
3063 * has to be flushed, zero is returned.
3064 */
3065static int
3066qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
3067{
3068 struct qeth_qdio_out_buffer *buffer;
3069 int flush_count = 0;
3070
3071 if (queue->do_pack) {
3072 if (atomic_read(&queue->used_buffers)
3073 <= QETH_LOW_WATERMARK_PACK) {
3074 /* switch PACKING -> non-PACKING */
3075 QETH_DBF_TEXT(trace, 6, "pack->np");
3076 if (queue->card->options.performance_stats)
3077 queue->card->perf_stats.sc_p_dp++;
3078 queue->do_pack = 0;
3079 /* flush packing buffers */
3080 buffer = &queue->bufs[queue->next_buf_to_fill];
3081 if ((atomic_read(&buffer->state) ==
3082 QETH_QDIO_BUF_EMPTY) &&
3083 (buffer->next_element_to_fill > 0)) {
3084 atomic_set(&buffer->state,QETH_QDIO_BUF_PRIMED);
3085 flush_count++;
3086 queue->next_buf_to_fill =
3087 (queue->next_buf_to_fill + 1) %
3088 QDIO_MAX_BUFFERS_PER_Q;
3089 }
3090 }
3091 }
3092 return flush_count;
3093}
3094
3095/*
3096 * Called to flush a packing buffer if no more pci flags are on the queue.
3097 * Checks if there is a packing buffer and prepares it to be flushed.
3098 * In that case returns 1, otherwise zero.
3099 */
3100static int
3101qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
3102{
3103 struct qeth_qdio_out_buffer *buffer;
3104
3105 buffer = &queue->bufs[queue->next_buf_to_fill];
3106 if((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
3107 (buffer->next_element_to_fill > 0)){
3108 /* it's a packing buffer */
3109 atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
3110 queue->next_buf_to_fill =
3111 (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q;
3112 return 1;
3113 }
3114 return 0;
3115}
3116
3117static void
3118qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
3119{
3120 int index;
3121 int flush_cnt = 0;
3122 int q_was_packing = 0;
3123
3124 /*
3125 * check if weed have to switch to non-packing mode or if
3126 * we have to get a pci flag out on the queue
3127 */
3128 if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) ||
3129 !atomic_read(&queue->set_pci_flags_count)){
3130 if (atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) ==
3131 QETH_OUT_Q_UNLOCKED) {
3132 /*
3133 * If we get in here, there was no action in
3134 * do_send_packet. So, we check if there is a
3135 * packing buffer to be flushed here.
3136 */
3137 netif_stop_queue(queue->card->dev);
3138 index = queue->next_buf_to_fill;
3139 q_was_packing = queue->do_pack;
3140 flush_cnt += qeth_switch_to_nonpacking_if_needed(queue);
3141 if (!flush_cnt &&
3142 !atomic_read(&queue->set_pci_flags_count))
3143 flush_cnt +=
3144 qeth_flush_buffers_on_no_pci(queue);
3145 if (queue->card->options.performance_stats &&
3146 q_was_packing)
3147 queue->card->perf_stats.bufs_sent_pack +=
3148 flush_cnt;
3149 if (flush_cnt)
3150 qeth_flush_buffers(queue, 1, index, flush_cnt);
3151 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
3152 }
3153 }
3154}
3155
3156static void
3157qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
3158 unsigned int qdio_error, unsigned int siga_error,
3159 unsigned int __queue, int first_element, int count,
3160 unsigned long card_ptr)
3161{
3162 struct qeth_card *card = (struct qeth_card *) card_ptr;
3163 struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
3164 struct qeth_qdio_out_buffer *buffer;
3165 int i;
3166
3167 QETH_DBF_TEXT(trace, 6, "qdouhdl");
3168 if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
3169 if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
3170 QETH_DBF_TEXT(trace, 2, "achkcond");
3171 QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
3172 QETH_DBF_TEXT_(trace, 2, "%08x", status);
3173 netif_stop_queue(card->dev);
3174 qeth_schedule_recovery(card);
3175 return;
3176 }
3177 }
3178 if (card->options.performance_stats) {
3179 card->perf_stats.outbound_handler_cnt++;
3180 card->perf_stats.outbound_handler_start_time =
3181 qeth_get_micros();
3182 }
3183 for(i = first_element; i < (first_element + count); ++i){
3184 buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
3185 /*we only handle the KICK_IT error by doing a recovery */
3186 if (qeth_handle_send_error(card, buffer,
3187 qdio_error, siga_error)
3188 == QETH_SEND_ERROR_KICK_IT){
3189 netif_stop_queue(card->dev);
3190 qeth_schedule_recovery(card);
3191 return;
3192 }
3193 qeth_clear_output_buffer(queue, buffer);
3194 }
3195 atomic_sub(count, &queue->used_buffers);
3196 /* check if we need to do something on this outbound queue */
3197 if (card->info.type != QETH_CARD_TYPE_IQD)
3198 qeth_check_outbound_queue(queue);
3199
3200 netif_wake_queue(queue->card->dev);
3201 if (card->options.performance_stats)
3202 card->perf_stats.outbound_handler_time += qeth_get_micros() -
3203 card->perf_stats.outbound_handler_start_time;
3204}
3205
3206static void
3207qeth_create_qib_param_field(struct qeth_card *card, char *param_field)
3208{
3209
3210 param_field[0] = _ascebc['P'];
3211 param_field[1] = _ascebc['C'];
3212 param_field[2] = _ascebc['I'];
3213 param_field[3] = _ascebc['T'];
3214 *((unsigned int *) (&param_field[4])) = QETH_PCI_THRESHOLD_A(card);
3215 *((unsigned int *) (&param_field[8])) = QETH_PCI_THRESHOLD_B(card);
3216 *((unsigned int *) (&param_field[12])) = QETH_PCI_TIMER_VALUE(card);
3217}
3218
3219static void
3220qeth_create_qib_param_field_blkt(struct qeth_card *card, char *param_field)
3221{
3222 param_field[16] = _ascebc['B'];
3223 param_field[17] = _ascebc['L'];
3224 param_field[18] = _ascebc['K'];
3225 param_field[19] = _ascebc['T'];
3226 *((unsigned int *) (&param_field[20])) = card->info.blkt.time_total;
3227 *((unsigned int *) (&param_field[24])) = card->info.blkt.inter_packet;
3228 *((unsigned int *) (&param_field[28])) = card->info.blkt.inter_packet_jumbo;
3229}
3230
3231static void
3232qeth_initialize_working_pool_list(struct qeth_card *card)
3233{
3234 struct qeth_buffer_pool_entry *entry;
3235
3236 QETH_DBF_TEXT(trace,5,"inwrklst");
3237
3238 list_for_each_entry(entry,
3239 &card->qdio.init_pool.entry_list, init_list) {
3240 qeth_put_buffer_pool_entry(card,entry);
3241 }
3242}
3243
3244static void
3245qeth_clear_working_pool_list(struct qeth_card *card)
3246{
3247 struct qeth_buffer_pool_entry *pool_entry, *tmp;
3248
3249 QETH_DBF_TEXT(trace,5,"clwrklst");
3250 list_for_each_entry_safe(pool_entry, tmp,
3251 &card->qdio.in_buf_pool.entry_list, list){
3252 list_del(&pool_entry->list);
3253 }
3254}
3255
3256static void
3257qeth_free_buffer_pool(struct qeth_card *card)
3258{
3259 struct qeth_buffer_pool_entry *pool_entry, *tmp;
3260 int i=0;
3261 QETH_DBF_TEXT(trace,5,"freepool");
3262 list_for_each_entry_safe(pool_entry, tmp,
3263 &card->qdio.init_pool.entry_list, init_list){
3264 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i)
3265 free_page((unsigned long)pool_entry->elements[i]);
3266 list_del(&pool_entry->init_list);
3267 kfree(pool_entry);
3268 }
3269}
3270
3271static int
3272qeth_alloc_buffer_pool(struct qeth_card *card)
3273{
3274 struct qeth_buffer_pool_entry *pool_entry;
3275 void *ptr;
3276 int i, j;
3277
3278 QETH_DBF_TEXT(trace,5,"alocpool");
3279 for (i = 0; i < card->qdio.init_pool.buf_count; ++i){
3280 pool_entry = kmalloc(sizeof(*pool_entry), GFP_KERNEL);
3281 if (!pool_entry){
3282 qeth_free_buffer_pool(card);
3283 return -ENOMEM;
3284 }
3285 for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){
3286 ptr = (void *) __get_free_page(GFP_KERNEL|GFP_DMA);
3287 if (!ptr) {
3288 while (j > 0)
3289 free_page((unsigned long)
3290 pool_entry->elements[--j]);
3291 kfree(pool_entry);
3292 qeth_free_buffer_pool(card);
3293 return -ENOMEM;
3294 }
3295 pool_entry->elements[j] = ptr;
3296 }
3297 list_add(&pool_entry->init_list,
3298 &card->qdio.init_pool.entry_list);
3299 }
3300 return 0;
3301}
3302
3303int
3304qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
3305{
3306 QETH_DBF_TEXT(trace, 2, "realcbp");
3307
3308 if ((card->state != CARD_STATE_DOWN) &&
3309 (card->state != CARD_STATE_RECOVER))
3310 return -EPERM;
3311
3312 /* TODO: steel/add buffers from/to a running card's buffer pool (?) */
3313 qeth_clear_working_pool_list(card);
3314 qeth_free_buffer_pool(card);
3315 card->qdio.in_buf_pool.buf_count = bufcnt;
3316 card->qdio.init_pool.buf_count = bufcnt;
3317 return qeth_alloc_buffer_pool(card);
3318}
3319
3320static int
3321qeth_alloc_qdio_buffers(struct qeth_card *card)
3322{
3323 int i, j;
3324
3325 QETH_DBF_TEXT(setup, 2, "allcqdbf");
3326
3327 if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED,
3328 QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
3329 return 0;
3330
3331 card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
3332 GFP_KERNEL|GFP_DMA);
3333 if (!card->qdio.in_q)
3334 goto out_nomem;
3335 QETH_DBF_TEXT(setup, 2, "inq");
3336 QETH_DBF_HEX(setup, 2, &card->qdio.in_q, sizeof(void *));
3337 memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q));
3338 /* give inbound qeth_qdio_buffers their qdio_buffers */
3339 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
3340 card->qdio.in_q->bufs[i].buffer =
3341 &card->qdio.in_q->qdio_bufs[i];
3342 /* inbound buffer pool */
3343 if (qeth_alloc_buffer_pool(card))
3344 goto out_freeinq;
3345 /* outbound */
3346 card->qdio.out_qs =
3347 kmalloc(card->qdio.no_out_queues *
3348 sizeof(struct qeth_qdio_out_q *), GFP_KERNEL);
3349 if (!card->qdio.out_qs)
3350 goto out_freepool;
3351 for (i = 0; i < card->qdio.no_out_queues; ++i) {
3352 card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
3353 GFP_KERNEL|GFP_DMA);
3354 if (!card->qdio.out_qs[i])
3355 goto out_freeoutq;
3356 QETH_DBF_TEXT_(setup, 2, "outq %i", i);
3357 QETH_DBF_HEX(setup, 2, &card->qdio.out_qs[i], sizeof(void *));
3358 memset(card->qdio.out_qs[i], 0, sizeof(struct qeth_qdio_out_q));
3359 card->qdio.out_qs[i]->queue_no = i;
3360 /* give outbound qeth_qdio_buffers their qdio_buffers */
3361 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j){
3362 card->qdio.out_qs[i]->bufs[j].buffer =
3363 &card->qdio.out_qs[i]->qdio_bufs[j];
3364 skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j].
3365 skb_list);
3366 lockdep_set_class(
3367 &card->qdio.out_qs[i]->bufs[j].skb_list.lock,
3368 &qdio_out_skb_queue_key);
3369 INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list);
3370 }
3371 }
3372 return 0;
3373
3374out_freeoutq:
3375 while (i > 0)
3376 kfree(card->qdio.out_qs[--i]);
3377 kfree(card->qdio.out_qs);
3378 card->qdio.out_qs = NULL;
3379out_freepool:
3380 qeth_free_buffer_pool(card);
3381out_freeinq:
3382 kfree(card->qdio.in_q);
3383 card->qdio.in_q = NULL;
3384out_nomem:
3385 atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
3386 return -ENOMEM;
3387}
3388
3389static void
3390qeth_free_qdio_buffers(struct qeth_card *card)
3391{
3392 int i, j;
3393
3394 QETH_DBF_TEXT(trace, 2, "freeqdbf");
3395 if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
3396 QETH_QDIO_UNINITIALIZED)
3397 return;
3398 kfree(card->qdio.in_q);
3399 card->qdio.in_q = NULL;
3400 /* inbound buffer pool */
3401 qeth_free_buffer_pool(card);
3402 /* free outbound qdio_qs */
3403 if (card->qdio.out_qs) {
3404 for (i = 0; i < card->qdio.no_out_queues; ++i) {
3405 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
3406 qeth_clear_output_buffer(card->qdio.out_qs[i],
3407 &card->qdio.out_qs[i]->bufs[j]);
3408 kfree(card->qdio.out_qs[i]);
3409 }
3410 kfree(card->qdio.out_qs);
3411 card->qdio.out_qs = NULL;
3412 }
3413}
3414
3415static void
3416qeth_clear_qdio_buffers(struct qeth_card *card)
3417{
3418 int i, j;
3419
3420 QETH_DBF_TEXT(trace, 2, "clearqdbf");
3421 /* clear outbound buffers to free skbs */
3422 for (i = 0; i < card->qdio.no_out_queues; ++i)
3423 if (card->qdio.out_qs && card->qdio.out_qs[i]) {
3424 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
3425 qeth_clear_output_buffer(card->qdio.out_qs[i],
3426 &card->qdio.out_qs[i]->bufs[j]);
3427 }
3428}
3429
3430static void
3431qeth_init_qdio_info(struct qeth_card *card)
3432{
3433 QETH_DBF_TEXT(setup, 4, "intqdinf");
3434 atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
3435 /* inbound */
3436 card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
3437 card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT;
3438 card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
3439 INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
3440 INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
3441}
3442
3443static int
3444qeth_init_qdio_queues(struct qeth_card *card)
3445{
3446 int i, j;
3447 int rc;
3448
3449 QETH_DBF_TEXT(setup, 2, "initqdqs");
3450
3451 /* inbound queue */
3452 memset(card->qdio.in_q->qdio_bufs, 0,
3453 QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
3454 qeth_initialize_working_pool_list(card);
3455 /*give only as many buffers to hardware as we have buffer pool entries*/
3456 for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
3457 qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]);
3458 card->qdio.in_q->next_buf_to_init = card->qdio.in_buf_pool.buf_count - 1;
3459 rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0,
3460 card->qdio.in_buf_pool.buf_count - 1, NULL);
3461 if (rc) {
3462 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3463 return rc;
3464 }
3465 rc = qdio_synchronize(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0);
3466 if (rc) {
3467 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
3468 return rc;
3469 }
3470 /* outbound queue */
3471 for (i = 0; i < card->qdio.no_out_queues; ++i){
3472 memset(card->qdio.out_qs[i]->qdio_bufs, 0,
3473 QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
3474 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j){
3475 qeth_clear_output_buffer(card->qdio.out_qs[i],
3476 &card->qdio.out_qs[i]->bufs[j]);
3477 }
3478 card->qdio.out_qs[i]->card = card;
3479 card->qdio.out_qs[i]->next_buf_to_fill = 0;
3480 card->qdio.out_qs[i]->do_pack = 0;
3481 atomic_set(&card->qdio.out_qs[i]->used_buffers,0);
3482 atomic_set(&card->qdio.out_qs[i]->set_pci_flags_count, 0);
3483 atomic_set(&card->qdio.out_qs[i]->state,
3484 QETH_OUT_Q_UNLOCKED);
3485 }
3486 return 0;
3487}
3488
3489static int
3490qeth_qdio_establish(struct qeth_card *card)
3491{
3492 struct qdio_initialize init_data;
3493 char *qib_param_field;
3494 struct qdio_buffer **in_sbal_ptrs;
3495 struct qdio_buffer **out_sbal_ptrs;
3496 int i, j, k;
3497 int rc = 0;
3498
3499 QETH_DBF_TEXT(setup, 2, "qdioest");
3500
3501 qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char),
3502 GFP_KERNEL);
3503 if (!qib_param_field)
3504 return -ENOMEM;
3505
3506 qeth_create_qib_param_field(card, qib_param_field);
3507 qeth_create_qib_param_field_blkt(card, qib_param_field);
3508
3509 in_sbal_ptrs = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(void *),
3510 GFP_KERNEL);
3511 if (!in_sbal_ptrs) {
3512 kfree(qib_param_field);
3513 return -ENOMEM;
3514 }
3515 for(i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
3516 in_sbal_ptrs[i] = (struct qdio_buffer *)
3517 virt_to_phys(card->qdio.in_q->bufs[i].buffer);
3518
3519 out_sbal_ptrs =
3520 kmalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q *
3521 sizeof(void *), GFP_KERNEL);
3522 if (!out_sbal_ptrs) {
3523 kfree(in_sbal_ptrs);
3524 kfree(qib_param_field);
3525 return -ENOMEM;
3526 }
3527 for(i = 0, k = 0; i < card->qdio.no_out_queues; ++i)
3528 for(j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k){
3529 out_sbal_ptrs[k] = (struct qdio_buffer *)
3530 virt_to_phys(card->qdio.out_qs[i]->
3531 bufs[j].buffer);
3532 }
3533
3534 memset(&init_data, 0, sizeof(struct qdio_initialize));
3535 init_data.cdev = CARD_DDEV(card);
3536 init_data.q_format = qeth_get_qdio_q_format(card);
3537 init_data.qib_param_field_format = 0;
3538 init_data.qib_param_field = qib_param_field;
3539 init_data.min_input_threshold = QETH_MIN_INPUT_THRESHOLD;
3540 init_data.max_input_threshold = QETH_MAX_INPUT_THRESHOLD;
3541 init_data.min_output_threshold = QETH_MIN_OUTPUT_THRESHOLD;
3542 init_data.max_output_threshold = QETH_MAX_OUTPUT_THRESHOLD;
3543 init_data.no_input_qs = 1;
3544 init_data.no_output_qs = card->qdio.no_out_queues;
3545 init_data.input_handler = (qdio_handler_t *)
3546 qeth_qdio_input_handler;
3547 init_data.output_handler = (qdio_handler_t *)
3548 qeth_qdio_output_handler;
3549 init_data.int_parm = (unsigned long) card;
3550 init_data.flags = QDIO_INBOUND_0COPY_SBALS |
3551 QDIO_OUTBOUND_0COPY_SBALS |
3552 QDIO_USE_OUTBOUND_PCIS;
3553 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3554 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
3555
3556 if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
3557 QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED)
3558 if ((rc = qdio_initialize(&init_data)))
3559 atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
3560
3561 kfree(out_sbal_ptrs);
3562 kfree(in_sbal_ptrs);
3563 kfree(qib_param_field);
3564 return rc;
3565}
3566
3567static int
3568qeth_qdio_activate(struct qeth_card *card)
3569{
3570 QETH_DBF_TEXT(setup,3,"qdioact");
3571 return qdio_activate(CARD_DDEV(card), 0);
3572}
3573
3574static int
3575qeth_clear_channel(struct qeth_channel *channel)
3576{
3577 unsigned long flags;
3578 struct qeth_card *card;
3579 int rc;
3580
3581 QETH_DBF_TEXT(trace,3,"clearch");
3582 card = CARD_FROM_CDEV(channel->ccwdev);
3583 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
3584 rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM);
3585 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
3586
3587 if (rc)
3588 return rc;
3589 rc = wait_event_interruptible_timeout(card->wait_q,
3590 channel->state==CH_STATE_STOPPED, QETH_TIMEOUT);
3591 if (rc == -ERESTARTSYS)
3592 return rc;
3593 if (channel->state != CH_STATE_STOPPED)
3594 return -ETIME;
3595 channel->state = CH_STATE_DOWN;
3596 return 0;
3597}
3598
3599static int
3600qeth_halt_channel(struct qeth_channel *channel)
3601{
3602 unsigned long flags;
3603 struct qeth_card *card;
3604 int rc;
3605
3606 QETH_DBF_TEXT(trace,3,"haltch");
3607 card = CARD_FROM_CDEV(channel->ccwdev);
3608 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
3609 rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM);
3610 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
3611
3612 if (rc)
3613 return rc;
3614 rc = wait_event_interruptible_timeout(card->wait_q,
3615 channel->state==CH_STATE_HALTED, QETH_TIMEOUT);
3616 if (rc == -ERESTARTSYS)
3617 return rc;
3618 if (channel->state != CH_STATE_HALTED)
3619 return -ETIME;
3620 return 0;
3621}
3622
3623static int
3624qeth_halt_channels(struct qeth_card *card)
3625{
3626 int rc1 = 0, rc2=0, rc3 = 0;
3627
3628 QETH_DBF_TEXT(trace,3,"haltchs");
3629 rc1 = qeth_halt_channel(&card->read);
3630 rc2 = qeth_halt_channel(&card->write);
3631 rc3 = qeth_halt_channel(&card->data);
3632 if (rc1)
3633 return rc1;
3634 if (rc2)
3635 return rc2;
3636 return rc3;
3637}
3638static int
3639qeth_clear_channels(struct qeth_card *card)
3640{
3641 int rc1 = 0, rc2=0, rc3 = 0;
3642
3643 QETH_DBF_TEXT(trace,3,"clearchs");
3644 rc1 = qeth_clear_channel(&card->read);
3645 rc2 = qeth_clear_channel(&card->write);
3646 rc3 = qeth_clear_channel(&card->data);
3647 if (rc1)
3648 return rc1;
3649 if (rc2)
3650 return rc2;
3651 return rc3;
3652}
3653
3654static int
3655qeth_clear_halt_card(struct qeth_card *card, int halt)
3656{
3657 int rc = 0;
3658
3659 QETH_DBF_TEXT(trace,3,"clhacrd");
3660 QETH_DBF_HEX(trace, 3, &card, sizeof(void *));
3661
3662 if (halt)
3663 rc = qeth_halt_channels(card);
3664 if (rc)
3665 return rc;
3666 return qeth_clear_channels(card);
3667}
3668
3669static int
3670qeth_qdio_clear_card(struct qeth_card *card, int use_halt)
3671{
3672 int rc = 0;
3673
3674 QETH_DBF_TEXT(trace,3,"qdioclr");
3675 switch (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ESTABLISHED,
3676 QETH_QDIO_CLEANING)) {
3677 case QETH_QDIO_ESTABLISHED:
3678 if ((rc = qdio_cleanup(CARD_DDEV(card),
3679 (card->info.type == QETH_CARD_TYPE_IQD) ?
3680 QDIO_FLAG_CLEANUP_USING_HALT :
3681 QDIO_FLAG_CLEANUP_USING_CLEAR)))
3682 QETH_DBF_TEXT_(trace, 3, "1err%d", rc);
3683 atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
3684 break;
3685 case QETH_QDIO_CLEANING:
3686 return rc;
3687 default:
3688 break;
3689 }
3690 if ((rc = qeth_clear_halt_card(card, use_halt)))
3691 QETH_DBF_TEXT_(trace, 3, "2err%d", rc);
3692 card->state = CARD_STATE_DOWN;
3693 return rc;
3694}
3695
3696static int
3697qeth_dm_act(struct qeth_card *card)
3698{
3699 int rc;
3700 struct qeth_cmd_buffer *iob;
3701
3702 QETH_DBF_TEXT(setup,2,"dmact");
3703
3704 iob = qeth_wait_for_buffer(&card->write);
3705 memcpy(iob->data, DM_ACT, DM_ACT_SIZE);
3706
3707 memcpy(QETH_DM_ACT_DEST_ADDR(iob->data),
3708 &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
3709 memcpy(QETH_DM_ACT_CONNECTION_TOKEN(iob->data),
3710 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
3711 rc = qeth_send_control_data(card, DM_ACT_SIZE, iob, NULL, NULL);
3712 return rc;
3713}
3714
3715static int
3716qeth_mpc_initialize(struct qeth_card *card)
3717{
3718 int rc;
3719
3720 QETH_DBF_TEXT(setup,2,"mpcinit");
3721
3722 if ((rc = qeth_issue_next_read(card))){
3723 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
3724 return rc;
3725 }
3726 if ((rc = qeth_cm_enable(card))){
3727 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
3728 goto out_qdio;
3729 }
3730 if ((rc = qeth_cm_setup(card))){
3731 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
3732 goto out_qdio;
3733 }
3734 if ((rc = qeth_ulp_enable(card))){
3735 QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
3736 goto out_qdio;
3737 }
3738 if ((rc = qeth_ulp_setup(card))){
3739 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
3740 goto out_qdio;
3741 }
3742 if ((rc = qeth_alloc_qdio_buffers(card))){
3743 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
3744 goto out_qdio;
3745 }
3746 if ((rc = qeth_qdio_establish(card))){
3747 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
3748 qeth_free_qdio_buffers(card);
3749 goto out_qdio;
3750 }
3751 if ((rc = qeth_qdio_activate(card))){
3752 QETH_DBF_TEXT_(setup, 2, "7err%d", rc);
3753 goto out_qdio;
3754 }
3755 if ((rc = qeth_dm_act(card))){
3756 QETH_DBF_TEXT_(setup, 2, "8err%d", rc);
3757 goto out_qdio;
3758 }
3759
3760 return 0;
3761out_qdio:
3762 qeth_qdio_clear_card(card, card->info.type!=QETH_CARD_TYPE_IQD);
3763 return rc;
3764}
3765
3766static struct net_device *
3767qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype)
3768{
3769 struct net_device *dev = NULL;
3770
3771 switch (type) {
3772 case QETH_CARD_TYPE_OSAE:
3773 switch (linktype) {
3774 case QETH_LINK_TYPE_LANE_TR:
3775 case QETH_LINK_TYPE_HSTR:
3776#ifdef CONFIG_TR
3777 dev = alloc_trdev(0);
3778#endif /* CONFIG_TR */
3779 break;
3780 default:
3781 dev = alloc_etherdev(0);
3782 }
3783 break;
3784 case QETH_CARD_TYPE_IQD:
3785 dev = alloc_netdev(0, "hsi%d", ether_setup);
3786 break;
3787 case QETH_CARD_TYPE_OSN:
3788 dev = alloc_netdev(0, "osn%d", ether_setup);
3789 break;
3790 default:
3791 dev = alloc_etherdev(0);
3792 }
3793 return dev;
3794}
3795
3796/*hard_header fake function; used in case fake_ll is set */
3797static int
3798qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
3799 unsigned short type, const void *daddr, const void *saddr,
3800 unsigned len)
3801{
3802 if(dev->type == ARPHRD_IEEE802_TR){
3803 struct trh_hdr *hdr;
3804 hdr = (struct trh_hdr *)skb_push(skb, QETH_FAKE_LL_LEN_TR);
3805 memcpy(hdr->saddr, dev->dev_addr, TR_ALEN);
3806 memcpy(hdr->daddr, "FAKELL", TR_ALEN);
3807 return QETH_FAKE_LL_LEN_TR;
3808
3809 } else {
3810 struct ethhdr *hdr;
3811 hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN_ETH);
3812 memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN);
3813 memcpy(hdr->h_dest, "FAKELL", ETH_ALEN);
3814 if (type != ETH_P_802_3)
3815 hdr->h_proto = htons(type);
3816 else
3817 hdr->h_proto = htons(len);
3818 return QETH_FAKE_LL_LEN_ETH;
3819
3820 }
3821}
3822
3823static const struct header_ops qeth_fake_ops = {
3824 .create = qeth_fake_header,
3825 .parse = qeth_hard_header_parse,
3826};
3827
3828static int
3829qeth_send_packet(struct qeth_card *, struct sk_buff *);
3830
3831static int
3832qeth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
3833{
3834 int rc;
3835 struct qeth_card *card;
3836
3837 QETH_DBF_TEXT(trace, 6, "hrdstxmi");
3838 card = (struct qeth_card *)dev->priv;
3839 if (skb==NULL) {
3840 card->stats.tx_dropped++;
3841 card->stats.tx_errors++;
3842 /* return OK; otherwise ksoftirqd goes to 100% */
3843 return NETDEV_TX_OK;
3844 }
3845 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
3846 card->stats.tx_dropped++;
3847 card->stats.tx_errors++;
3848 card->stats.tx_carrier_errors++;
3849 dev_kfree_skb_any(skb);
3850 /* return OK; otherwise ksoftirqd goes to 100% */
3851 return NETDEV_TX_OK;
3852 }
3853 if (card->options.performance_stats) {
3854 card->perf_stats.outbound_cnt++;
3855 card->perf_stats.outbound_start_time = qeth_get_micros();
3856 }
3857 netif_stop_queue(dev);
3858 if ((rc = qeth_send_packet(card, skb))) {
3859 if (rc == -EBUSY) {
3860 return NETDEV_TX_BUSY;
3861 } else {
3862 card->stats.tx_errors++;
3863 card->stats.tx_dropped++;
3864 dev_kfree_skb_any(skb);
3865 /*set to OK; otherwise ksoftirqd goes to 100% */
3866 rc = NETDEV_TX_OK;
3867 }
3868 }
3869 netif_wake_queue(dev);
3870 if (card->options.performance_stats)
3871 card->perf_stats.outbound_time += qeth_get_micros() -
3872 card->perf_stats.outbound_start_time;
3873 return rc;
3874}
3875
3876static int
3877qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card)
3878{
3879 int rc = 0;
3880#ifdef CONFIG_QETH_VLAN
3881 struct vlan_group *vg;
3882 int i;
3883
3884 if (!(vg = card->vlangrp))
3885 return rc;
3886
3887 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++){
3888 if (vlan_group_get_device(vg, i) == dev){
3889 rc = QETH_VLAN_CARD;
3890 break;
3891 }
3892 }
3893 if (rc && !(vlan_dev_info(dev)->real_dev->priv == (void *)card))
3894 return 0;
3895
3896#endif
3897 return rc;
3898}
3899
3900static int
3901qeth_verify_dev(struct net_device *dev)
3902{
3903 struct qeth_card *card;
3904 unsigned long flags;
3905 int rc = 0;
3906
3907 read_lock_irqsave(&qeth_card_list.rwlock, flags);
3908 list_for_each_entry(card, &qeth_card_list.list, list){
3909 if (card->dev == dev){
3910 rc = QETH_REAL_CARD;
3911 break;
3912 }
3913 rc = qeth_verify_vlan_dev(dev, card);
3914 if (rc)
3915 break;
3916 }
3917 read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
3918
3919 return rc;
3920}
3921
3922static struct qeth_card *
3923qeth_get_card_from_dev(struct net_device *dev)
3924{
3925 struct qeth_card *card = NULL;
3926 int rc;
3927
3928 rc = qeth_verify_dev(dev);
3929 if (rc == QETH_REAL_CARD)
3930 card = (struct qeth_card *)dev->priv;
3931 else if (rc == QETH_VLAN_CARD)
3932 card = (struct qeth_card *)
3933 vlan_dev_info(dev)->real_dev->priv;
3934
3935 QETH_DBF_TEXT_(trace, 4, "%d", rc);
3936 return card ;
3937}
3938
3939static void
3940qeth_tx_timeout(struct net_device *dev)
3941{
3942 struct qeth_card *card;
3943
3944 card = (struct qeth_card *) dev->priv;
3945 card->stats.tx_errors++;
3946 qeth_schedule_recovery(card);
3947}
3948
3949static int
3950qeth_open(struct net_device *dev)
3951{
3952 struct qeth_card *card;
3953
3954 QETH_DBF_TEXT(trace, 4, "qethopen");
3955
3956 card = (struct qeth_card *) dev->priv;
3957
3958 if (card->state != CARD_STATE_SOFTSETUP)
3959 return -ENODEV;
3960
3961 if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
3962 (card->options.layer2) &&
3963 (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
3964 QETH_DBF_TEXT(trace,4,"nomacadr");
3965 return -EPERM;
3966 }
3967 card->data.state = CH_STATE_UP;
3968 card->state = CARD_STATE_UP;
3969 card->dev->flags |= IFF_UP;
3970 netif_start_queue(dev);
3971
3972 if (!card->lan_online && netif_carrier_ok(dev))
3973 netif_carrier_off(dev);
3974 return 0;
3975}
3976
3977static int
3978qeth_stop(struct net_device *dev)
3979{
3980 struct qeth_card *card;
3981
3982 QETH_DBF_TEXT(trace, 4, "qethstop");
3983
3984 card = (struct qeth_card *) dev->priv;
3985
3986 netif_tx_disable(dev);
3987 card->dev->flags &= ~IFF_UP;
3988 if (card->state == CARD_STATE_UP)
3989 card->state = CARD_STATE_SOFTSETUP;
3990 return 0;
3991}
3992
3993static int
3994qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
3995{
3996 int cast_type = RTN_UNSPEC;
3997
3998 if (card->info.type == QETH_CARD_TYPE_OSN)
3999 return cast_type;
4000
4001 if (skb->dst && skb->dst->neighbour){
4002 cast_type = skb->dst->neighbour->type;
4003 if ((cast_type == RTN_BROADCAST) ||
4004 (cast_type == RTN_MULTICAST) ||
4005 (cast_type == RTN_ANYCAST))
4006 return cast_type;
4007 else
4008 return RTN_UNSPEC;
4009 }
4010 /* try something else */
4011 if (skb->protocol == ETH_P_IPV6)
4012 return (skb_network_header(skb)[24] == 0xff) ?
4013 RTN_MULTICAST : 0;
4014 else if (skb->protocol == ETH_P_IP)
4015 return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ?
4016 RTN_MULTICAST : 0;
4017 /* ... */
4018 if (!memcmp(skb->data, skb->dev->broadcast, 6))
4019 return RTN_BROADCAST;
4020 else {
4021 u16 hdr_mac;
4022
4023 hdr_mac = *((u16 *)skb->data);
4024 /* tr multicast? */
4025 switch (card->info.link_type) {
4026 case QETH_LINK_TYPE_HSTR:
4027 case QETH_LINK_TYPE_LANE_TR:
4028 if ((hdr_mac == QETH_TR_MAC_NC) ||
4029 (hdr_mac == QETH_TR_MAC_C))
4030 return RTN_MULTICAST;
4031 break;
4032 /* eth or so multicast? */
4033 default:
4034 if ((hdr_mac == QETH_ETH_MAC_V4) ||
4035 (hdr_mac == QETH_ETH_MAC_V6))
4036 return RTN_MULTICAST;
4037 }
4038 }
4039 return cast_type;
4040}
4041
4042static int
4043qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
4044 int ipv, int cast_type)
4045{
4046 if (!ipv && (card->info.type == QETH_CARD_TYPE_OSAE))
4047 return card->qdio.default_out_queue;
4048 switch (card->qdio.no_out_queues) {
4049 case 4:
4050 if (cast_type && card->info.is_multicast_different)
4051 return card->info.is_multicast_different &
4052 (card->qdio.no_out_queues - 1);
4053 if (card->qdio.do_prio_queueing && (ipv == 4)) {
4054 const u8 tos = ip_hdr(skb)->tos;
4055
4056 if (card->qdio.do_prio_queueing==QETH_PRIO_Q_ING_TOS){
4057 if (tos & IP_TOS_NOTIMPORTANT)
4058 return 3;
4059 if (tos & IP_TOS_HIGHRELIABILITY)
4060 return 2;
4061 if (tos & IP_TOS_HIGHTHROUGHPUT)
4062 return 1;
4063 if (tos & IP_TOS_LOWDELAY)
4064 return 0;
4065 }
4066 if (card->qdio.do_prio_queueing==QETH_PRIO_Q_ING_PREC)
4067 return 3 - (tos >> 6);
4068 } else if (card->qdio.do_prio_queueing && (ipv == 6)) {
4069 /* TODO: IPv6!!! */
4070 }
4071 return card->qdio.default_out_queue;
4072 case 1: /* fallthrough for single-out-queue 1920-device */
4073 default:
4074 return card->qdio.default_out_queue;
4075 }
4076}
4077
4078static inline int
4079qeth_get_ip_version(struct sk_buff *skb)
4080{
4081 switch (skb->protocol) {
4082 case ETH_P_IPV6:
4083 return 6;
4084 case ETH_P_IP:
4085 return 4;
4086 default:
4087 return 0;
4088 }
4089}
4090
4091static struct qeth_hdr *
4092__qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
4093{
4094#ifdef CONFIG_QETH_VLAN
4095 u16 *tag;
4096 if (card->vlangrp && vlan_tx_tag_present(skb) &&
4097 ((ipv == 6) || card->options.layer2) ) {
4098 /*
4099 * Move the mac addresses (6 bytes src, 6 bytes dest)
4100 * to the beginning of the new header. We are using three
4101 * memcpys instead of one memmove to save cycles.
4102 */
4103 skb_push(skb, VLAN_HLEN);
4104 skb_copy_to_linear_data(skb, skb->data + 4, 4);
4105 skb_copy_to_linear_data_offset(skb, 4, skb->data + 8, 4);
4106 skb_copy_to_linear_data_offset(skb, 8, skb->data + 12, 4);
4107 tag = (u16 *)(skb->data + 12);
4108 /*
4109 * first two bytes = ETH_P_8021Q (0x8100)
4110 * second two bytes = VLANID
4111 */
4112 *tag = __constant_htons(ETH_P_8021Q);
4113 *(tag + 1) = htons(vlan_tx_tag_get(skb));
4114 }
4115#endif
4116 return ((struct qeth_hdr *)
4117 qeth_push_skb(card, skb, sizeof(struct qeth_hdr)));
4118}
4119
4120static void
4121__qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb)
4122{
4123 if (orig_skb != new_skb)
4124 dev_kfree_skb_any(new_skb);
4125}
4126
4127static struct sk_buff *
4128qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb,
4129 struct qeth_hdr **hdr, int ipv)
4130{
4131 struct sk_buff *new_skb, *new_skb2;
4132
4133 QETH_DBF_TEXT(trace, 6, "prepskb");
4134 new_skb = skb;
4135 new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
4136 if (!new_skb)
4137 return NULL;
4138 new_skb2 = qeth_realloc_headroom(card, new_skb,
4139 sizeof(struct qeth_hdr));
4140 if (!new_skb2) {
4141 __qeth_free_new_skb(skb, new_skb);
4142 return NULL;
4143 }
4144 if (new_skb != skb)
4145 __qeth_free_new_skb(new_skb2, new_skb);
4146 new_skb = new_skb2;
4147 *hdr = __qeth_prepare_skb(card, new_skb, ipv);
4148 if (*hdr == NULL) {
4149 __qeth_free_new_skb(skb, new_skb);
4150 return NULL;
4151 }
4152 return new_skb;
4153}
4154
4155static inline u8
4156qeth_get_qeth_hdr_flags4(int cast_type)
4157{
4158 if (cast_type == RTN_MULTICAST)
4159 return QETH_CAST_MULTICAST;
4160 if (cast_type == RTN_BROADCAST)
4161 return QETH_CAST_BROADCAST;
4162 return QETH_CAST_UNICAST;
4163}
4164
4165static inline u8
4166qeth_get_qeth_hdr_flags6(int cast_type)
4167{
4168 u8 ct = QETH_HDR_PASSTHRU | QETH_HDR_IPV6;
4169 if (cast_type == RTN_MULTICAST)
4170 return ct | QETH_CAST_MULTICAST;
4171 if (cast_type == RTN_ANYCAST)
4172 return ct | QETH_CAST_ANYCAST;
4173 if (cast_type == RTN_BROADCAST)
4174 return ct | QETH_CAST_BROADCAST;
4175 return ct | QETH_CAST_UNICAST;
4176}
4177
4178static void
4179qeth_layer2_get_packet_type(struct qeth_card *card, struct qeth_hdr *hdr,
4180 struct sk_buff *skb)
4181{
4182 __u16 hdr_mac;
4183
4184 if (!memcmp(skb->data+QETH_HEADER_SIZE,
4185 skb->dev->broadcast,6)) { /* broadcast? */
4186 *(__u32 *)hdr->hdr.l2.flags |=
4187 QETH_LAYER2_FLAG_BROADCAST << 8;
4188 return;
4189 }
4190 hdr_mac=*((__u16*)skb->data);
4191 /* tr multicast? */
4192 switch (card->info.link_type) {
4193 case QETH_LINK_TYPE_HSTR:
4194 case QETH_LINK_TYPE_LANE_TR:
4195 if ((hdr_mac == QETH_TR_MAC_NC) ||
4196 (hdr_mac == QETH_TR_MAC_C) )
4197 *(__u32 *)hdr->hdr.l2.flags |=
4198 QETH_LAYER2_FLAG_MULTICAST << 8;
4199 else
4200 *(__u32 *)hdr->hdr.l2.flags |=
4201 QETH_LAYER2_FLAG_UNICAST << 8;
4202 break;
4203 /* eth or so multicast? */
4204 default:
4205 if ( (hdr_mac==QETH_ETH_MAC_V4) ||
4206 (hdr_mac==QETH_ETH_MAC_V6) )
4207 *(__u32 *)hdr->hdr.l2.flags |=
4208 QETH_LAYER2_FLAG_MULTICAST << 8;
4209 else
4210 *(__u32 *)hdr->hdr.l2.flags |=
4211 QETH_LAYER2_FLAG_UNICAST << 8;
4212 }
4213}
4214
4215static void
4216qeth_layer2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
4217 struct sk_buff *skb, int cast_type)
4218{
4219 memset(hdr, 0, sizeof(struct qeth_hdr));
4220 hdr->hdr.l2.id = QETH_HEADER_TYPE_LAYER2;
4221
4222 /* set byte 0 to "0x02" and byte 3 to casting flags */
4223 if (cast_type==RTN_MULTICAST)
4224 *(__u32 *)hdr->hdr.l2.flags |= QETH_LAYER2_FLAG_MULTICAST << 8;
4225 else if (cast_type==RTN_BROADCAST)
4226 *(__u32 *)hdr->hdr.l2.flags |= QETH_LAYER2_FLAG_BROADCAST << 8;
4227 else
4228 qeth_layer2_get_packet_type(card, hdr, skb);
4229
4230 hdr->hdr.l2.pkt_length = skb->len-QETH_HEADER_SIZE;
4231#ifdef CONFIG_QETH_VLAN
4232 /* VSWITCH relies on the VLAN
4233 * information to be present in
4234 * the QDIO header */
4235 if ((card->vlangrp != NULL) &&
4236 vlan_tx_tag_present(skb)) {
4237 *(__u32 *)hdr->hdr.l2.flags |= QETH_LAYER2_FLAG_VLAN << 8;
4238 hdr->hdr.l2.vlan_id = vlan_tx_tag_get(skb);
4239 }
4240#endif
4241}
4242
4243void
4244qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
4245 struct sk_buff *skb, int ipv, int cast_type)
4246{
4247 QETH_DBF_TEXT(trace, 6, "fillhdr");
4248
4249 memset(hdr, 0, sizeof(struct qeth_hdr));
4250 if (card->options.layer2) {
4251 qeth_layer2_fill_header(card, hdr, skb, cast_type);
4252 return;
4253 }
4254 hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
4255 hdr->hdr.l3.ext_flags = 0;
4256#ifdef CONFIG_QETH_VLAN
4257 /*
4258 * before we're going to overwrite this location with next hop ip.
4259 * v6 uses passthrough, v4 sets the tag in the QDIO header.
4260 */
4261 if (card->vlangrp && vlan_tx_tag_present(skb)) {
4262 hdr->hdr.l3.ext_flags = (ipv == 4) ?
4263 QETH_HDR_EXT_VLAN_FRAME :
4264 QETH_HDR_EXT_INCLUDE_VLAN_TAG;
4265 hdr->hdr.l3.vlan_id = vlan_tx_tag_get(skb);
4266 }
4267#endif /* CONFIG_QETH_VLAN */
4268 hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr);
4269 if (ipv == 4) { /* IPv4 */
4270 hdr->hdr.l3.flags = qeth_get_qeth_hdr_flags4(cast_type);
4271 memset(hdr->hdr.l3.dest_addr, 0, 12);
4272 if ((skb->dst) && (skb->dst->neighbour)) {
4273 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
4274 *((u32 *) skb->dst->neighbour->primary_key);
4275 } else {
4276 /* fill in destination address used in ip header */
4277 *((u32 *)(&hdr->hdr.l3.dest_addr[12])) =
4278 ip_hdr(skb)->daddr;
4279 }
4280 } else if (ipv == 6) { /* IPv6 or passthru */
4281 hdr->hdr.l3.flags = qeth_get_qeth_hdr_flags6(cast_type);
4282 if ((skb->dst) && (skb->dst->neighbour)) {
4283 memcpy(hdr->hdr.l3.dest_addr,
4284 skb->dst->neighbour->primary_key, 16);
4285 } else {
4286 /* fill in destination address used in ip header */
4287 memcpy(hdr->hdr.l3.dest_addr,
4288 &ipv6_hdr(skb)->daddr, 16);
4289 }
4290 } else { /* passthrough */
4291 if((skb->dev->type == ARPHRD_IEEE802_TR) &&
4292 !memcmp(skb->data + sizeof(struct qeth_hdr) +
4293 sizeof(__u16), skb->dev->broadcast, 6)) {
4294 hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
4295 QETH_HDR_PASSTHRU;
4296 } else if (!memcmp(skb->data + sizeof(struct qeth_hdr),
4297 skb->dev->broadcast, 6)) { /* broadcast? */
4298 hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
4299 QETH_HDR_PASSTHRU;
4300 } else {
4301 hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ?
4302 QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU :
4303 QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;
4304 }
4305 }
4306}
4307
4308static void
4309__qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
4310 int is_tso, int *next_element_to_fill)
4311{
4312 int length = skb->len;
4313 int length_here;
4314 int element;
4315 char *data;
4316 int first_lap ;
4317
4318 element = *next_element_to_fill;
4319 data = skb->data;
4320 first_lap = (is_tso == 0 ? 1 : 0);
4321
4322 while (length > 0) {
4323 /* length_here is the remaining amount of data in this page */
4324 length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE);
4325 if (length < length_here)
4326 length_here = length;
4327
4328 buffer->element[element].addr = data;
4329 buffer->element[element].length = length_here;
4330 length -= length_here;
4331 if (!length) {
4332 if (first_lap)
4333 buffer->element[element].flags = 0;
4334 else
4335 buffer->element[element].flags =
4336 SBAL_FLAGS_LAST_FRAG;
4337 } else {
4338 if (first_lap)
4339 buffer->element[element].flags =
4340 SBAL_FLAGS_FIRST_FRAG;
4341 else
4342 buffer->element[element].flags =
4343 SBAL_FLAGS_MIDDLE_FRAG;
4344 }
4345 data += length_here;
4346 element++;
4347 first_lap = 0;
4348 }
4349 *next_element_to_fill = element;
4350}
4351
4352static int
4353qeth_fill_buffer(struct qeth_qdio_out_q *queue,
4354 struct qeth_qdio_out_buffer *buf,
4355 struct sk_buff *skb)
4356{
4357 struct qdio_buffer *buffer;
4358 struct qeth_hdr_tso *hdr;
4359 int flush_cnt = 0, hdr_len, large_send = 0;
4360
4361 QETH_DBF_TEXT(trace, 6, "qdfillbf");
4362
4363 buffer = buf->buffer;
4364 atomic_inc(&skb->users);
4365 skb_queue_tail(&buf->skb_list, skb);
4366
4367 hdr = (struct qeth_hdr_tso *) skb->data;
4368 /*check first on TSO ....*/
4369 if (hdr->hdr.hdr.l3.id == QETH_HEADER_TYPE_TSO) {
4370 int element = buf->next_element_to_fill;
4371
4372 hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len;
4373 /*fill first buffer entry only with header information */
4374 buffer->element[element].addr = skb->data;
4375 buffer->element[element].length = hdr_len;
4376 buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
4377 buf->next_element_to_fill++;
4378 skb->data += hdr_len;
4379 skb->len -= hdr_len;
4380 large_send = 1;
4381 }
4382 if (skb_shinfo(skb)->nr_frags == 0)
4383 __qeth_fill_buffer(skb, buffer, large_send,
4384 (int *)&buf->next_element_to_fill);
4385 else
4386 __qeth_fill_buffer_frag(skb, buffer, large_send,
4387 (int *)&buf->next_element_to_fill);
4388
4389 if (!queue->do_pack) {
4390 QETH_DBF_TEXT(trace, 6, "fillbfnp");
4391 /* set state to PRIMED -> will be flushed */
4392 atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
4393 flush_cnt = 1;
4394 } else {
4395 QETH_DBF_TEXT(trace, 6, "fillbfpa");
4396 if (queue->card->options.performance_stats)
4397 queue->card->perf_stats.skbs_sent_pack++;
4398 if (buf->next_element_to_fill >=
4399 QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
4400 /*
4401 * packed buffer if full -> set state PRIMED
4402 * -> will be flushed
4403 */
4404 atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
4405 flush_cnt = 1;
4406 }
4407 }
4408 return flush_cnt;
4409}
4410
4411static int
4412qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4413 struct sk_buff *skb, struct qeth_hdr *hdr,
4414 int elements_needed,
4415 struct qeth_eddp_context *ctx)
4416{
4417 struct qeth_qdio_out_buffer *buffer;
4418 int buffers_needed = 0;
4419 int flush_cnt = 0;
4420 int index;
4421
4422 QETH_DBF_TEXT(trace, 6, "dosndpfa");
4423
4424 /* spin until we get the queue ... */
4425 while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
4426 QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
4427 /* ... now we've got the queue */
4428 index = queue->next_buf_to_fill;
4429 buffer = &queue->bufs[queue->next_buf_to_fill];
4430 /*
4431 * check if buffer is empty to make sure that we do not 'overtake'
4432 * ourselves and try to fill a buffer that is already primed
4433 */
4434 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
4435 goto out;
4436 if (ctx == NULL)
4437 queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
4438 QDIO_MAX_BUFFERS_PER_Q;
4439 else {
4440 buffers_needed = qeth_eddp_check_buffers_for_context(queue,ctx);
4441 if (buffers_needed < 0)
4442 goto out;
4443 queue->next_buf_to_fill =
4444 (queue->next_buf_to_fill + buffers_needed) %
4445 QDIO_MAX_BUFFERS_PER_Q;
4446 }
4447 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4448 if (ctx == NULL) {
4449 qeth_fill_buffer(queue, buffer, skb);
4450 qeth_flush_buffers(queue, 0, index, 1);
4451 } else {
4452 flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
4453 WARN_ON(buffers_needed != flush_cnt);
4454 qeth_flush_buffers(queue, 0, index, flush_cnt);
4455 }
4456 return 0;
4457out:
4458 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4459 return -EBUSY;
4460}
4461
4462static int
4463qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4464 struct sk_buff *skb, struct qeth_hdr *hdr,
4465 int elements_needed, struct qeth_eddp_context *ctx)
4466{
4467 struct qeth_qdio_out_buffer *buffer;
4468 int start_index;
4469 int flush_count = 0;
4470 int do_pack = 0;
4471 int tmp;
4472 int rc = 0;
4473
4474 QETH_DBF_TEXT(trace, 6, "dosndpkt");
4475
4476 /* spin until we get the queue ... */
4477 while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
4478 QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
4479 start_index = queue->next_buf_to_fill;
4480 buffer = &queue->bufs[queue->next_buf_to_fill];
4481 /*
4482 * check if buffer is empty to make sure that we do not 'overtake'
4483 * ourselves and try to fill a buffer that is already primed
4484 */
4485 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
4486 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4487 return -EBUSY;
4488 }
4489 /* check if we need to switch packing state of this queue */
4490 qeth_switch_to_packing_if_needed(queue);
4491 if (queue->do_pack){
4492 do_pack = 1;
4493 if (ctx == NULL) {
4494 /* does packet fit in current buffer? */
4495 if((QETH_MAX_BUFFER_ELEMENTS(card) -
4496 buffer->next_element_to_fill) < elements_needed){
4497 /* ... no -> set state PRIMED */
4498 atomic_set(&buffer->state,QETH_QDIO_BUF_PRIMED);
4499 flush_count++;
4500 queue->next_buf_to_fill =
4501 (queue->next_buf_to_fill + 1) %
4502 QDIO_MAX_BUFFERS_PER_Q;
4503 buffer = &queue->bufs[queue->next_buf_to_fill];
4504 /* we did a step forward, so check buffer state
4505 * again */
4506 if (atomic_read(&buffer->state) !=
4507 QETH_QDIO_BUF_EMPTY){
4508 qeth_flush_buffers(queue, 0, start_index, flush_count);
4509 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
4510 return -EBUSY;
4511 }
4512 }
4513 } else {
4514 /* check if we have enough elements (including following
4515 * free buffers) to handle eddp context */
4516 if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){
4517 if (net_ratelimit())
4518 PRINT_WARN("eddp tx_dropped 1\n");
4519 rc = -EBUSY;
4520 goto out;
4521 }
4522 }
4523 }
4524 if (ctx == NULL)
4525 tmp = qeth_fill_buffer(queue, buffer, skb);
4526 else {
4527 tmp = qeth_eddp_fill_buffer(queue,ctx,queue->next_buf_to_fill);
4528 if (tmp < 0) {
4529 printk("eddp tx_dropped 2\n");
4530 rc = - EBUSY;
4531 goto out;
4532 }
4533 }
4534 queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
4535 QDIO_MAX_BUFFERS_PER_Q;
4536 flush_count += tmp;
4537out:
4538 if (flush_count)
4539 qeth_flush_buffers(queue, 0, start_index, flush_count);
4540 else if (!atomic_read(&queue->set_pci_flags_count))
4541 atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
4542 /*
4543 * queue->state will go from LOCKED -> UNLOCKED or from
4544 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
4545 * (switch packing state or flush buffer to get another pci flag out).
4546 * In that case we will enter this loop
4547 */
4548 while (atomic_dec_return(&queue->state)){
4549 flush_count = 0;
4550 start_index = queue->next_buf_to_fill;
4551 /* check if we can go back to non-packing state */
4552 flush_count += qeth_switch_to_nonpacking_if_needed(queue);
4553 /*
4554 * check if we need to flush a packing buffer to get a pci
4555 * flag out on the queue
4556 */
4557 if (!flush_count && !atomic_read(&queue->set_pci_flags_count))
4558 flush_count += qeth_flush_buffers_on_no_pci(queue);
4559 if (flush_count)
4560 qeth_flush_buffers(queue, 0, start_index, flush_count);
4561 }
4562 /* at this point the queue is UNLOCKED again */
4563 if (queue->card->options.performance_stats && do_pack)
4564 queue->card->perf_stats.bufs_sent_pack += flush_count;
4565
4566 return rc;
4567}
4568
4569static int
4570qeth_get_elements_no(struct qeth_card *card, void *hdr,
4571 struct sk_buff *skb, int elems)
4572{
4573 int elements_needed = 0;
4574
4575 if (skb_shinfo(skb)->nr_frags > 0)
4576 elements_needed = (skb_shinfo(skb)->nr_frags + 1);
4577 if (elements_needed == 0)
4578 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
4579 + skb->len) >> PAGE_SHIFT);
4580 if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){
4581 PRINT_ERR("Invalid size of IP packet "
4582 "(Number=%d / Length=%d). Discarded.\n",
4583 (elements_needed+elems), skb->len);
4584 return 0;
4585 }
4586 return elements_needed;
4587}
4588
4589static void qeth_tx_csum(struct sk_buff *skb)
4590{
4591 int tlen;
4592
4593 if (skb->protocol == htons(ETH_P_IP)) {
4594 tlen = ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2);
4595 switch (ip_hdr(skb)->protocol) {
4596 case IPPROTO_TCP:
4597 tcp_hdr(skb)->check = 0;
4598 tcp_hdr(skb)->check = csum_tcpudp_magic(
4599 ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
4600 tlen, ip_hdr(skb)->protocol,
4601 skb_checksum(skb, skb_transport_offset(skb),
4602 tlen, 0));
4603 break;
4604 case IPPROTO_UDP:
4605 udp_hdr(skb)->check = 0;
4606 udp_hdr(skb)->check = csum_tcpudp_magic(
4607 ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
4608 tlen, ip_hdr(skb)->protocol,
4609 skb_checksum(skb, skb_transport_offset(skb),
4610 tlen, 0));
4611 break;
4612 }
4613 } else if (skb->protocol == htons(ETH_P_IPV6)) {
4614 switch (ipv6_hdr(skb)->nexthdr) {
4615 case IPPROTO_TCP:
4616 tcp_hdr(skb)->check = 0;
4617 tcp_hdr(skb)->check = csum_ipv6_magic(
4618 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
4619 ipv6_hdr(skb)->payload_len,
4620 ipv6_hdr(skb)->nexthdr,
4621 skb_checksum(skb, skb_transport_offset(skb),
4622 ipv6_hdr(skb)->payload_len, 0));
4623 break;
4624 case IPPROTO_UDP:
4625 udp_hdr(skb)->check = 0;
4626 udp_hdr(skb)->check = csum_ipv6_magic(
4627 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
4628 ipv6_hdr(skb)->payload_len,
4629 ipv6_hdr(skb)->nexthdr,
4630 skb_checksum(skb, skb_transport_offset(skb),
4631 ipv6_hdr(skb)->payload_len, 0));
4632 break;
4633 }
4634 }
4635}
4636
4637static int
4638qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4639{
4640 int ipv = 0;
4641 int cast_type;
4642 struct qeth_qdio_out_q *queue;
4643 struct qeth_hdr *hdr = NULL;
4644 int elements_needed = 0;
4645 enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
4646 struct qeth_eddp_context *ctx = NULL;
4647 int tx_bytes = skb->len;
4648 unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
4649 unsigned short tso_size = skb_shinfo(skb)->gso_size;
4650 struct sk_buff *new_skb, *new_skb2;
4651 int rc;
4652
4653 QETH_DBF_TEXT(trace, 6, "sendpkt");
4654
4655 new_skb = skb;
4656 if ((card->info.type == QETH_CARD_TYPE_OSN) &&
4657 (skb->protocol == htons(ETH_P_IPV6)))
4658 return -EPERM;
4659 cast_type = qeth_get_cast_type(card, skb);
4660 if ((cast_type == RTN_BROADCAST) &&
4661 (card->info.broadcast_capable == 0))
4662 return -EPERM;
4663 queue = card->qdio.out_qs
4664 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
4665 if (!card->options.layer2) {
4666 ipv = qeth_get_ip_version(skb);
4667 if ((card->dev->header_ops == &qeth_fake_ops) && ipv) {
4668 new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
4669 if (!new_skb)
4670 return -ENOMEM;
4671 if(card->dev->type == ARPHRD_IEEE802_TR){
4672 skb_pull(new_skb, QETH_FAKE_LL_LEN_TR);
4673 } else {
4674 skb_pull(new_skb, QETH_FAKE_LL_LEN_ETH);
4675 }
4676 }
4677 }
4678 if (skb_is_gso(skb))
4679 large_send = card->options.large_send;
4680 /* check on OSN device*/
4681 if (card->info.type == QETH_CARD_TYPE_OSN)
4682 hdr = (struct qeth_hdr *)new_skb->data;
4683 /*are we able to do TSO ? */
4684 if ((large_send == QETH_LARGE_SEND_TSO) &&
4685 (cast_type == RTN_UNSPEC)) {
4686 rc = qeth_tso_prepare_packet(card, new_skb, ipv, cast_type);
4687 if (rc) {
4688 __qeth_free_new_skb(skb, new_skb);
4689 return rc;
4690 }
4691 elements_needed++;
4692 } else if (card->info.type != QETH_CARD_TYPE_OSN) {
4693 new_skb2 = qeth_prepare_skb(card, new_skb, &hdr, ipv);
4694 if (!new_skb2) {
4695 __qeth_free_new_skb(skb, new_skb);
4696 return -EINVAL;
4697 }
4698 if (new_skb != skb)
4699 __qeth_free_new_skb(new_skb2, new_skb);
4700 new_skb = new_skb2;
4701 qeth_fill_header(card, hdr, new_skb, ipv, cast_type);
4702 }
4703 if (large_send == QETH_LARGE_SEND_EDDP) {
4704 ctx = qeth_eddp_create_context(card, new_skb, hdr,
4705 skb->sk->sk_protocol);
4706 if (ctx == NULL) {
4707 __qeth_free_new_skb(skb, new_skb);
4708 PRINT_WARN("could not create eddp context\n");
4709 return -EINVAL;
4710 }
4711 } else {
4712 int elems = qeth_get_elements_no(card,(void*) hdr, new_skb,
4713 elements_needed);
4714 if (!elems) {
4715 __qeth_free_new_skb(skb, new_skb);
4716 return -EINVAL;
4717 }
4718 elements_needed += elems;
4719 }
4720
4721 if ((large_send == QETH_LARGE_SEND_NO) &&
4722 (skb->ip_summed == CHECKSUM_PARTIAL))
4723 qeth_tx_csum(new_skb);
4724
4725 if (card->info.type != QETH_CARD_TYPE_IQD)
4726 rc = qeth_do_send_packet(card, queue, new_skb, hdr,
4727 elements_needed, ctx);
4728 else {
4729 if ((!card->options.layer2) &&
4730 (ipv == 0)) {
4731 __qeth_free_new_skb(skb, new_skb);
4732 return -EPERM;
4733 }
4734 rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
4735 elements_needed, ctx);
4736 }
4737 if (!rc) {
4738 card->stats.tx_packets++;
4739 card->stats.tx_bytes += tx_bytes;
4740 if (new_skb != skb)
4741 dev_kfree_skb_any(skb);
4742 if (card->options.performance_stats) {
4743 if (tso_size &&
4744 !(large_send == QETH_LARGE_SEND_NO)) {
4745 card->perf_stats.large_send_bytes += tx_bytes;
4746 card->perf_stats.large_send_cnt++;
4747 }
4748 if (nr_frags > 0) {
4749 card->perf_stats.sg_skbs_sent++;
4750 /* nr_frags + skb->data */
4751 card->perf_stats.sg_frags_sent +=
4752 nr_frags + 1;
4753 }
4754 }
4755 } else {
4756 card->stats.tx_dropped++;
4757 __qeth_free_new_skb(skb, new_skb);
4758 }
4759 if (ctx != NULL) {
4760 /* drop creator's reference */
4761 qeth_eddp_put_context(ctx);
4762 /* free skb; it's not referenced by a buffer */
4763 if (!rc)
4764 dev_kfree_skb_any(new_skb);
4765 }
4766 return rc;
4767}
4768
4769static int
4770qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
4771{
4772 struct qeth_card *card = (struct qeth_card *) dev->priv;
4773 int rc = 0;
4774
4775 switch(regnum){
4776 case MII_BMCR: /* Basic mode control register */
4777 rc = BMCR_FULLDPLX;
4778 if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH)&&
4779 (card->info.link_type != QETH_LINK_TYPE_OSN) &&
4780 (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
4781 rc |= BMCR_SPEED100;
4782 break;
4783 case MII_BMSR: /* Basic mode status register */
4784 rc = BMSR_ERCAP | BMSR_ANEGCOMPLETE | BMSR_LSTATUS |
4785 BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | BMSR_100FULL |
4786 BMSR_100BASE4;
4787 break;
4788 case MII_PHYSID1: /* PHYS ID 1 */
4789 rc = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 8) |
4790 dev->dev_addr[2];
4791 rc = (rc >> 5) & 0xFFFF;
4792 break;
4793 case MII_PHYSID2: /* PHYS ID 2 */
4794 rc = (dev->dev_addr[2] << 10) & 0xFFFF;
4795 break;
4796 case MII_ADVERTISE: /* Advertisement control reg */
4797 rc = ADVERTISE_ALL;
4798 break;
4799 case MII_LPA: /* Link partner ability reg */
4800 rc = LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL |
4801 LPA_100BASE4 | LPA_LPACK;
4802 break;
4803 case MII_EXPANSION: /* Expansion register */
4804 break;
4805 case MII_DCOUNTER: /* disconnect counter */
4806 break;
4807 case MII_FCSCOUNTER: /* false carrier counter */
4808 break;
4809 case MII_NWAYTEST: /* N-way auto-neg test register */
4810 break;
4811 case MII_RERRCOUNTER: /* rx error counter */
4812 rc = card->stats.rx_errors;
4813 break;
4814 case MII_SREVISION: /* silicon revision */
4815 break;
4816 case MII_RESV1: /* reserved 1 */
4817 break;
4818 case MII_LBRERROR: /* loopback, rx, bypass error */
4819 break;
4820 case MII_PHYADDR: /* physical address */
4821 break;
4822 case MII_RESV2: /* reserved 2 */
4823 break;
4824 case MII_TPISTATUS: /* TPI status for 10mbps */
4825 break;
4826 case MII_NCONFIG: /* network interface config */
4827 break;
4828 default:
4829 break;
4830 }
4831 return rc;
4832}
4833
4834
4835static const char *
4836qeth_arp_get_error_cause(int *rc)
4837{
4838 switch (*rc) {
4839 case QETH_IPA_ARP_RC_FAILED:
4840 *rc = -EIO;
4841 return "operation failed";
4842 case QETH_IPA_ARP_RC_NOTSUPP:
4843 *rc = -EOPNOTSUPP;
4844 return "operation not supported";
4845 case QETH_IPA_ARP_RC_OUT_OF_RANGE:
4846 *rc = -EINVAL;
4847 return "argument out of range";
4848 case QETH_IPA_ARP_RC_Q_NOTSUPP:
4849 *rc = -EOPNOTSUPP;
4850 return "query operation not supported";
4851 case QETH_IPA_ARP_RC_Q_NO_DATA:
4852 *rc = -ENOENT;
4853 return "no query data available";
4854 default:
4855 return "unknown error";
4856 }
4857}
4858
4859static int
4860qeth_send_simple_setassparms(struct qeth_card *, enum qeth_ipa_funcs,
4861 __u16, long);
4862
4863static int
4864qeth_arp_set_no_entries(struct qeth_card *card, int no_entries)
4865{
4866 int tmp;
4867 int rc;
4868
4869 QETH_DBF_TEXT(trace,3,"arpstnoe");
4870
4871 /*
4872 * currently GuestLAN only supports the ARP assist function
4873 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES;
4874 * thus we say EOPNOTSUPP for this ARP function
4875 */
4876 if (card->info.guestlan)
4877 return -EOPNOTSUPP;
4878 if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
4879 PRINT_WARN("ARP processing not supported "
4880 "on %s!\n", QETH_CARD_IFNAME(card));
4881 return -EOPNOTSUPP;
4882 }
4883 rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
4884 IPA_CMD_ASS_ARP_SET_NO_ENTRIES,
4885 no_entries);
4886 if (rc) {
4887 tmp = rc;
4888 PRINT_WARN("Could not set number of ARP entries on %s: "
4889 "%s (0x%x/%d)\n",
4890 QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
4891 tmp, tmp);
4892 }
4893 return rc;
4894}
4895
4896static void
4897qeth_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo,
4898 struct qeth_arp_query_data *qdata,
4899 int entry_size, int uentry_size)
4900{
4901 char *entry_ptr;
4902 char *uentry_ptr;
4903 int i;
4904
4905 entry_ptr = (char *)&qdata->data;
4906 uentry_ptr = (char *)(qinfo->udata + qinfo->udata_offset);
4907 for (i = 0; i < qdata->no_entries; ++i){
4908 /* strip off 32 bytes "media specific information" */
4909 memcpy(uentry_ptr, (entry_ptr + 32), entry_size - 32);
4910 entry_ptr += entry_size;
4911 uentry_ptr += uentry_size;
4912 }
4913}
4914
4915static int
4916qeth_arp_query_cb(struct qeth_card *card, struct qeth_reply *reply,
4917 unsigned long data)
4918{
4919 struct qeth_ipa_cmd *cmd;
4920 struct qeth_arp_query_data *qdata;
4921 struct qeth_arp_query_info *qinfo;
4922 int entry_size;
4923 int uentry_size;
4924 int i;
4925
4926 QETH_DBF_TEXT(trace,4,"arpquecb");
4927
4928 qinfo = (struct qeth_arp_query_info *) reply->param;
4929 cmd = (struct qeth_ipa_cmd *) data;
4930 if (cmd->hdr.return_code) {
4931 QETH_DBF_TEXT_(trace,4,"qaer1%i", cmd->hdr.return_code);
4932 return 0;
4933 }
4934 if (cmd->data.setassparms.hdr.return_code) {
4935 cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
4936 QETH_DBF_TEXT_(trace,4,"qaer2%i", cmd->hdr.return_code);
4937 return 0;
4938 }
4939 qdata = &cmd->data.setassparms.data.query_arp;
4940 switch(qdata->reply_bits){
4941 case 5:
4942 uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry5);
4943 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
4944 uentry_size = sizeof(struct qeth_arp_qi_entry5_short);
4945 break;
4946 case 7:
4947 /* fall through to default */
4948 default:
4949 /* tr is the same as eth -> entry7 */
4950 uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry7);
4951 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
4952 uentry_size = sizeof(struct qeth_arp_qi_entry7_short);
4953 break;
4954 }
4955 /* check if there is enough room in userspace */
4956 if ((qinfo->udata_len - qinfo->udata_offset) <
4957 qdata->no_entries * uentry_size){
4958 QETH_DBF_TEXT_(trace, 4, "qaer3%i", -ENOMEM);
4959 cmd->hdr.return_code = -ENOMEM;
4960 PRINT_WARN("query ARP user space buffer is too small for "
4961 "the returned number of ARP entries. "
4962 "Aborting query!\n");
4963 goto out_error;
4964 }
4965 QETH_DBF_TEXT_(trace, 4, "anore%i",
4966 cmd->data.setassparms.hdr.number_of_replies);
4967 QETH_DBF_TEXT_(trace, 4, "aseqn%i", cmd->data.setassparms.hdr.seq_no);
4968 QETH_DBF_TEXT_(trace, 4, "anoen%i", qdata->no_entries);
4969
4970 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) {
4971 /* strip off "media specific information" */
4972 qeth_copy_arp_entries_stripped(qinfo, qdata, entry_size,
4973 uentry_size);
4974 } else
4975 /*copy entries to user buffer*/
4976 memcpy(qinfo->udata + qinfo->udata_offset,
4977 (char *)&qdata->data, qdata->no_entries*uentry_size);
4978
4979 qinfo->no_entries += qdata->no_entries;
4980 qinfo->udata_offset += (qdata->no_entries*uentry_size);
4981 /* check if all replies received ... */
4982 if (cmd->data.setassparms.hdr.seq_no <
4983 cmd->data.setassparms.hdr.number_of_replies)
4984 return 1;
4985 memcpy(qinfo->udata, &qinfo->no_entries, 4);
4986 /* keep STRIP_ENTRIES flag so the user program can distinguish
4987 * stripped entries from normal ones */
4988 if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
4989 qdata->reply_bits |= QETH_QARP_STRIP_ENTRIES;
4990 memcpy(qinfo->udata + QETH_QARP_MASK_OFFSET,&qdata->reply_bits,2);
4991 return 0;
4992out_error:
4993 i = 0;
4994 memcpy(qinfo->udata, &i, 4);
4995 return 0;
4996}
4997
4998static int
4999qeth_send_ipa_arp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
5000 int len, int (*reply_cb)(struct qeth_card *,
5001 struct qeth_reply *,
5002 unsigned long),
5003 void *reply_param)
5004{
5005 QETH_DBF_TEXT(trace,4,"sendarp");
5006
5007 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
5008 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
5009 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
5010 return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
5011 reply_cb, reply_param);
5012}
5013
5014static int
5015qeth_send_ipa_snmp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
5016 int len, int (*reply_cb)(struct qeth_card *,
5017 struct qeth_reply *,
5018 unsigned long),
5019 void *reply_param)
5020{
5021 u16 s1, s2;
5022
5023 QETH_DBF_TEXT(trace,4,"sendsnmp");
5024
5025 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
5026 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
5027 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
5028 /* adjust PDU length fields in IPA_PDU_HEADER */
5029 s1 = (u32) IPA_PDU_HEADER_SIZE + len;
5030 s2 = (u32) len;
5031 memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
5032 memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
5033 memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
5034 memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
5035 return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
5036 reply_cb, reply_param);
5037}
5038
5039static struct qeth_cmd_buffer *
5040qeth_get_setassparms_cmd(struct qeth_card *, enum qeth_ipa_funcs,
5041 __u16, __u16, enum qeth_prot_versions);
5042static int
5043qeth_arp_query(struct qeth_card *card, char __user *udata)
5044{
5045 struct qeth_cmd_buffer *iob;
5046 struct qeth_arp_query_info qinfo = {0, };
5047 int tmp;
5048 int rc;
5049
5050 QETH_DBF_TEXT(trace,3,"arpquery");
5051
5052 if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
5053 IPA_ARP_PROCESSING)) {
5054 PRINT_WARN("ARP processing not supported "
5055 "on %s!\n", QETH_CARD_IFNAME(card));
5056 return -EOPNOTSUPP;
5057 }
5058 /* get size of userspace buffer and mask_bits -> 6 bytes */
5059 if (copy_from_user(&qinfo, udata, 6))
5060 return -EFAULT;
5061 if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL)))
5062 return -ENOMEM;
5063 qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET;
5064 iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
5065 IPA_CMD_ASS_ARP_QUERY_INFO,
5066 sizeof(int),QETH_PROT_IPV4);
5067
5068 rc = qeth_send_ipa_arp_cmd(card, iob,
5069 QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
5070 qeth_arp_query_cb, (void *)&qinfo);
5071 if (rc) {
5072 tmp = rc;
5073 PRINT_WARN("Error while querying ARP cache on %s: %s "
5074 "(0x%x/%d)\n",
5075 QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
5076 tmp, tmp);
5077 if (copy_to_user(udata, qinfo.udata, 4))
5078 rc = -EFAULT;
5079 } else {
5080 if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
5081 rc = -EFAULT;
5082 }
5083 kfree(qinfo.udata);
5084 return rc;
5085}
5086
5087/**
5088 * SNMP command callback
5089 */
5090static int
5091qeth_snmp_command_cb(struct qeth_card *card, struct qeth_reply *reply,
5092 unsigned long sdata)
5093{
5094 struct qeth_ipa_cmd *cmd;
5095 struct qeth_arp_query_info *qinfo;
5096 struct qeth_snmp_cmd *snmp;
5097 unsigned char *data;
5098 __u16 data_len;
5099
5100 QETH_DBF_TEXT(trace,3,"snpcmdcb");
5101
5102 cmd = (struct qeth_ipa_cmd *) sdata;
5103 data = (unsigned char *)((char *)cmd - reply->offset);
5104 qinfo = (struct qeth_arp_query_info *) reply->param;
5105 snmp = &cmd->data.setadapterparms.data.snmp;
5106
5107 if (cmd->hdr.return_code) {
5108 QETH_DBF_TEXT_(trace,4,"scer1%i", cmd->hdr.return_code);
5109 return 0;
5110 }
5111 if (cmd->data.setadapterparms.hdr.return_code) {
5112 cmd->hdr.return_code = cmd->data.setadapterparms.hdr.return_code;
5113 QETH_DBF_TEXT_(trace,4,"scer2%i", cmd->hdr.return_code);
5114 return 0;
5115 }
5116 data_len = *((__u16*)QETH_IPA_PDU_LEN_PDU1(data));
5117 if (cmd->data.setadapterparms.hdr.seq_no == 1)
5118 data_len -= (__u16)((char *)&snmp->data - (char *)cmd);
5119 else
5120 data_len -= (__u16)((char*)&snmp->request - (char *)cmd);
5121
5122 /* check if there is enough room in userspace */
5123 if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
5124 QETH_DBF_TEXT_(trace, 4, "scer3%i", -ENOMEM);
5125 cmd->hdr.return_code = -ENOMEM;
5126 return 0;
5127 }
5128 QETH_DBF_TEXT_(trace, 4, "snore%i",
5129 cmd->data.setadapterparms.hdr.used_total);
5130 QETH_DBF_TEXT_(trace, 4, "sseqn%i", cmd->data.setadapterparms.hdr.seq_no);
5131 /*copy entries to user buffer*/
5132 if (cmd->data.setadapterparms.hdr.seq_no == 1) {
5133 memcpy(qinfo->udata + qinfo->udata_offset,
5134 (char *)snmp,
5135 data_len + offsetof(struct qeth_snmp_cmd,data));
5136 qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data);
5137 } else {
5138 memcpy(qinfo->udata + qinfo->udata_offset,
5139 (char *)&snmp->request, data_len);
5140 }
5141 qinfo->udata_offset += data_len;
5142 /* check if all replies received ... */
5143 QETH_DBF_TEXT_(trace, 4, "srtot%i",
5144 cmd->data.setadapterparms.hdr.used_total);
5145 QETH_DBF_TEXT_(trace, 4, "srseq%i",
5146 cmd->data.setadapterparms.hdr.seq_no);
5147 if (cmd->data.setadapterparms.hdr.seq_no <
5148 cmd->data.setadapterparms.hdr.used_total)
5149 return 1;
5150 return 0;
5151}
5152
5153static struct qeth_cmd_buffer *
5154qeth_get_ipacmd_buffer(struct qeth_card *, enum qeth_ipa_cmds,
5155 enum qeth_prot_versions );
5156
5157static struct qeth_cmd_buffer *
5158qeth_get_adapter_cmd(struct qeth_card *card, __u32 command, __u32 cmdlen)
5159{
5160 struct qeth_cmd_buffer *iob;
5161 struct qeth_ipa_cmd *cmd;
5162
5163 iob = qeth_get_ipacmd_buffer(card,IPA_CMD_SETADAPTERPARMS,
5164 QETH_PROT_IPV4);
5165 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
5166 cmd->data.setadapterparms.hdr.cmdlength = cmdlen;
5167 cmd->data.setadapterparms.hdr.command_code = command;
5168 cmd->data.setadapterparms.hdr.used_total = 1;
5169 cmd->data.setadapterparms.hdr.seq_no = 1;
5170
5171 return iob;
5172}
5173
5174/**
5175 * function to send SNMP commands to OSA-E card
5176 */
5177static int
5178qeth_snmp_command(struct qeth_card *card, char __user *udata)
5179{
5180 struct qeth_cmd_buffer *iob;
5181 struct qeth_ipa_cmd *cmd;
5182 struct qeth_snmp_ureq *ureq;
5183 int req_len;
5184 struct qeth_arp_query_info qinfo = {0, };
5185 int rc = 0;
5186
5187 QETH_DBF_TEXT(trace,3,"snmpcmd");
5188
5189 if (card->info.guestlan)
5190 return -EOPNOTSUPP;
5191
5192 if ((!qeth_adp_supported(card,IPA_SETADP_SET_SNMP_CONTROL)) &&
5193 (!card->options.layer2) ) {
5194 PRINT_WARN("SNMP Query MIBS not supported "
5195 "on %s!\n", QETH_CARD_IFNAME(card));
5196 return -EOPNOTSUPP;
5197 }
5198 /* skip 4 bytes (data_len struct member) to get req_len */
5199 if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
5200 return -EFAULT;
5201 ureq = kmalloc(req_len+sizeof(struct qeth_snmp_ureq_hdr), GFP_KERNEL);
5202 if (!ureq) {
5203 QETH_DBF_TEXT(trace, 2, "snmpnome");
5204 return -ENOMEM;
5205 }
5206 if (copy_from_user(ureq, udata,
5207 req_len+sizeof(struct qeth_snmp_ureq_hdr))){
5208 kfree(ureq);
5209 return -EFAULT;
5210 }
5211 qinfo.udata_len = ureq->hdr.data_len;
5212 if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL))){
5213 kfree(ureq);
5214 return -ENOMEM;
5215 }
5216 qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr);
5217
5218 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL,
5219 QETH_SNMP_SETADP_CMDLENGTH + req_len);
5220 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
5221 memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
5222 rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
5223 qeth_snmp_command_cb, (void *)&qinfo);
5224 if (rc)
5225 PRINT_WARN("SNMP command failed on %s: (0x%x)\n",
5226 QETH_CARD_IFNAME(card), rc);
5227 else {
5228 if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
5229 rc = -EFAULT;
5230 }
5231
5232 kfree(ureq);
5233 kfree(qinfo.udata);
5234 return rc;
5235}
5236
5237static int
5238qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *,
5239 unsigned long);
5240
5241static int
5242qeth_default_setadapterparms_cb(struct qeth_card *card,
5243 struct qeth_reply *reply,
5244 unsigned long data);
5245static int
5246qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,
5247 __u16, long,
5248 int (*reply_cb)
5249 (struct qeth_card *, struct qeth_reply *, unsigned long),
5250 void *reply_param);
5251
5252static int
5253qeth_arp_add_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry)
5254{
5255 struct qeth_cmd_buffer *iob;
5256 char buf[16];
5257 int tmp;
5258 int rc;
5259
5260 QETH_DBF_TEXT(trace,3,"arpadent");
5261
5262 /*
5263 * currently GuestLAN only supports the ARP assist function
5264 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY;
5265 * thus we say EOPNOTSUPP for this ARP function
5266 */
5267 if (card->info.guestlan)
5268 return -EOPNOTSUPP;
5269 if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
5270 PRINT_WARN("ARP processing not supported "
5271 "on %s!\n", QETH_CARD_IFNAME(card));
5272 return -EOPNOTSUPP;
5273 }
5274
5275 iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
5276 IPA_CMD_ASS_ARP_ADD_ENTRY,
5277 sizeof(struct qeth_arp_cache_entry),
5278 QETH_PROT_IPV4);
5279 rc = qeth_send_setassparms(card, iob,
5280 sizeof(struct qeth_arp_cache_entry),
5281 (unsigned long) entry,
5282 qeth_default_setassparms_cb, NULL);
5283 if (rc) {
5284 tmp = rc;
5285 qeth_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
5286 PRINT_WARN("Could not add ARP entry for address %s on %s: "
5287 "%s (0x%x/%d)\n",
5288 buf, QETH_CARD_IFNAME(card),
5289 qeth_arp_get_error_cause(&rc), tmp, tmp);
5290 }
5291 return rc;
5292}
5293
5294static int
5295qeth_arp_remove_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry)
5296{
5297 struct qeth_cmd_buffer *iob;
5298 char buf[16] = {0, };
5299 int tmp;
5300 int rc;
5301
5302 QETH_DBF_TEXT(trace,3,"arprment");
5303
5304 /*
5305 * currently GuestLAN only supports the ARP assist function
5306 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY;
5307 * thus we say EOPNOTSUPP for this ARP function
5308 */
5309 if (card->info.guestlan)
5310 return -EOPNOTSUPP;
5311 if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
5312 PRINT_WARN("ARP processing not supported "
5313 "on %s!\n", QETH_CARD_IFNAME(card));
5314 return -EOPNOTSUPP;
5315 }
5316 memcpy(buf, entry, 12);
5317 iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
5318 IPA_CMD_ASS_ARP_REMOVE_ENTRY,
5319 12,
5320 QETH_PROT_IPV4);
5321 rc = qeth_send_setassparms(card, iob,
5322 12, (unsigned long)buf,
5323 qeth_default_setassparms_cb, NULL);
5324 if (rc) {
5325 tmp = rc;
5326 memset(buf, 0, 16);
5327 qeth_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
5328 PRINT_WARN("Could not delete ARP entry for address %s on %s: "
5329 "%s (0x%x/%d)\n",
5330 buf, QETH_CARD_IFNAME(card),
5331 qeth_arp_get_error_cause(&rc), tmp, tmp);
5332 }
5333 return rc;
5334}
5335
5336static int
5337qeth_arp_flush_cache(struct qeth_card *card)
5338{
5339 int rc;
5340 int tmp;
5341
5342 QETH_DBF_TEXT(trace,3,"arpflush");
5343
5344 /*
5345 * currently GuestLAN only supports the ARP assist function
5346 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE;
5347 * thus we say EOPNOTSUPP for this ARP function
5348 */
5349 if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD))
5350 return -EOPNOTSUPP;
5351 if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
5352 PRINT_WARN("ARP processing not supported "
5353 "on %s!\n", QETH_CARD_IFNAME(card));
5354 return -EOPNOTSUPP;
5355 }
5356 rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
5357 IPA_CMD_ASS_ARP_FLUSH_CACHE, 0);
5358 if (rc){
5359 tmp = rc;
5360 PRINT_WARN("Could not flush ARP cache on %s: %s (0x%x/%d)\n",
5361 QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
5362 tmp, tmp);
5363 }
5364 return rc;
5365}
5366
5367static int
5368qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5369{
5370 struct qeth_card *card = (struct qeth_card *)dev->priv;
5371 struct qeth_arp_cache_entry arp_entry;
5372 struct mii_ioctl_data *mii_data;
5373 int rc = 0;
5374
5375 if (!card)
5376 return -ENODEV;
5377
5378 if ((card->state != CARD_STATE_UP) &&
5379 (card->state != CARD_STATE_SOFTSETUP))
5380 return -ENODEV;
5381
5382 if (card->info.type == QETH_CARD_TYPE_OSN)
5383 return -EPERM;
5384
5385 switch (cmd){
5386 case SIOC_QETH_ARP_SET_NO_ENTRIES:
5387 if ( !capable(CAP_NET_ADMIN) ||
5388 (card->options.layer2) ) {
5389 rc = -EPERM;
5390 break;
5391 }
5392 rc = qeth_arp_set_no_entries(card, rq->ifr_ifru.ifru_ivalue);
5393 break;
5394 case SIOC_QETH_ARP_QUERY_INFO:
5395 if ( !capable(CAP_NET_ADMIN) ||
5396 (card->options.layer2) ) {
5397 rc = -EPERM;
5398 break;
5399 }
5400 rc = qeth_arp_query(card, rq->ifr_ifru.ifru_data);
5401 break;
5402 case SIOC_QETH_ARP_ADD_ENTRY:
5403 if ( !capable(CAP_NET_ADMIN) ||
5404 (card->options.layer2) ) {
5405 rc = -EPERM;
5406 break;
5407 }
5408 if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
5409 sizeof(struct qeth_arp_cache_entry)))
5410 rc = -EFAULT;
5411 else
5412 rc = qeth_arp_add_entry(card, &arp_entry);
5413 break;
5414 case SIOC_QETH_ARP_REMOVE_ENTRY:
5415 if ( !capable(CAP_NET_ADMIN) ||
5416 (card->options.layer2) ) {
5417 rc = -EPERM;
5418 break;
5419 }
5420 if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
5421 sizeof(struct qeth_arp_cache_entry)))
5422 rc = -EFAULT;
5423 else
5424 rc = qeth_arp_remove_entry(card, &arp_entry);
5425 break;
5426 case SIOC_QETH_ARP_FLUSH_CACHE:
5427 if ( !capable(CAP_NET_ADMIN) ||
5428 (card->options.layer2) ) {
5429 rc = -EPERM;
5430 break;
5431 }
5432 rc = qeth_arp_flush_cache(card);
5433 break;
5434 case SIOC_QETH_ADP_SET_SNMP_CONTROL:
5435 rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
5436 break;
5437 case SIOC_QETH_GET_CARD_TYPE:
5438 if ((card->info.type == QETH_CARD_TYPE_OSAE) &&
5439 !card->info.guestlan)
5440 return 1;
5441 return 0;
5442 break;
5443 case SIOCGMIIPHY:
5444 mii_data = if_mii(rq);
5445 mii_data->phy_id = 0;
5446 break;
5447 case SIOCGMIIREG:
5448 mii_data = if_mii(rq);
5449 if (mii_data->phy_id != 0)
5450 rc = -EINVAL;
5451 else
5452 mii_data->val_out = qeth_mdio_read(dev,mii_data->phy_id,
5453 mii_data->reg_num);
5454 break;
5455 default:
5456 rc = -EOPNOTSUPP;
5457 }
5458 if (rc)
5459 QETH_DBF_TEXT_(trace, 2, "ioce%d", rc);
5460 return rc;
5461}
5462
5463static struct net_device_stats *
5464qeth_get_stats(struct net_device *dev)
5465{
5466 struct qeth_card *card;
5467
5468 card = (struct qeth_card *) (dev->priv);
5469
5470 QETH_DBF_TEXT(trace,5,"getstat");
5471
5472 return &card->stats;
5473}
5474
5475static int
5476qeth_change_mtu(struct net_device *dev, int new_mtu)
5477{
5478 struct qeth_card *card;
5479 char dbf_text[15];
5480
5481 card = (struct qeth_card *) (dev->priv);
5482
5483 QETH_DBF_TEXT(trace,4,"chgmtu");
5484 sprintf(dbf_text, "%8x", new_mtu);
5485 QETH_DBF_TEXT(trace,4,dbf_text);
5486
5487 if (new_mtu < 64)
5488 return -EINVAL;
5489 if (new_mtu > 65535)
5490 return -EINVAL;
5491 if ((!qeth_is_supported(card,IPA_IP_FRAGMENTATION)) &&
5492 (!qeth_mtu_is_valid(card, new_mtu)))
5493 return -EINVAL;
5494 dev->mtu = new_mtu;
5495 return 0;
5496}
5497
5498#ifdef CONFIG_QETH_VLAN
5499static void
5500qeth_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
5501{
5502 struct qeth_card *card;
5503 unsigned long flags;
5504
5505 QETH_DBF_TEXT(trace,4,"vlanreg");
5506
5507 card = (struct qeth_card *) dev->priv;
5508 spin_lock_irqsave(&card->vlanlock, flags);
5509 card->vlangrp = grp;
5510 spin_unlock_irqrestore(&card->vlanlock, flags);
5511}
5512
5513static void
5514qeth_free_vlan_buffer(struct qeth_card *card, struct qeth_qdio_out_buffer *buf,
5515 unsigned short vid)
5516{
5517 int i;
5518 struct sk_buff *skb;
5519 struct sk_buff_head tmp_list;
5520
5521 skb_queue_head_init(&tmp_list);
5522 lockdep_set_class(&tmp_list.lock, &qdio_out_skb_queue_key);
5523 for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){
5524 while ((skb = skb_dequeue(&buf->skb_list))){
5525 if (vlan_tx_tag_present(skb) &&
5526 (vlan_tx_tag_get(skb) == vid)) {
5527 atomic_dec(&skb->users);
5528 dev_kfree_skb(skb);
5529 } else
5530 skb_queue_tail(&tmp_list, skb);
5531 }
5532 }
5533 while ((skb = skb_dequeue(&tmp_list)))
5534 skb_queue_tail(&buf->skb_list, skb);
5535}
5536
5537static void
5538qeth_free_vlan_skbs(struct qeth_card *card, unsigned short vid)
5539{
5540 int i, j;
5541
5542 QETH_DBF_TEXT(trace, 4, "frvlskbs");
5543 for (i = 0; i < card->qdio.no_out_queues; ++i){
5544 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
5545 qeth_free_vlan_buffer(card, &card->qdio.
5546 out_qs[i]->bufs[j], vid);
5547 }
5548}
5549
5550static void
5551qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
5552{
5553 struct in_device *in_dev;
5554 struct in_ifaddr *ifa;
5555 struct qeth_ipaddr *addr;
5556
5557 QETH_DBF_TEXT(trace, 4, "frvaddr4");
5558
5559 rcu_read_lock();
5560 in_dev = __in_dev_get_rcu(vlan_group_get_device(card->vlangrp, vid));
5561 if (!in_dev)
5562 goto out;
5563 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
5564 addr = qeth_get_addr_buffer(QETH_PROT_IPV4);
5565 if (addr){
5566 addr->u.a4.addr = ifa->ifa_address;
5567 addr->u.a4.mask = ifa->ifa_mask;
5568 addr->type = QETH_IP_TYPE_NORMAL;
5569 if (!qeth_delete_ip(card, addr))
5570 kfree(addr);
5571 }
5572 }
5573out:
5574 rcu_read_unlock();
5575}
5576
5577static void
5578qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
5579{
5580#ifdef CONFIG_QETH_IPV6
5581 struct inet6_dev *in6_dev;
5582 struct inet6_ifaddr *ifa;
5583 struct qeth_ipaddr *addr;
5584
5585 QETH_DBF_TEXT(trace, 4, "frvaddr6");
5586
5587 in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid));
5588 if (!in6_dev)
5589 return;
5590 for (ifa = in6_dev->addr_list; ifa; ifa = ifa->lst_next){
5591 addr = qeth_get_addr_buffer(QETH_PROT_IPV6);
5592 if (addr){
5593 memcpy(&addr->u.a6.addr, &ifa->addr,
5594 sizeof(struct in6_addr));
5595 addr->u.a6.pfxlen = ifa->prefix_len;
5596 addr->type = QETH_IP_TYPE_NORMAL;
5597 if (!qeth_delete_ip(card, addr))
5598 kfree(addr);
5599 }
5600 }
5601 in6_dev_put(in6_dev);
5602#endif /* CONFIG_QETH_IPV6 */
5603}
5604
5605static void
5606qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid)
5607{
5608 if (card->options.layer2 || !card->vlangrp)
5609 return;
5610 qeth_free_vlan_addresses4(card, vid);
5611 qeth_free_vlan_addresses6(card, vid);
5612}
5613
5614static int
5615qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
5616 struct qeth_reply *reply,
5617 unsigned long data)
5618{
5619 struct qeth_ipa_cmd *cmd;
5620
5621 QETH_DBF_TEXT(trace, 2, "L2sdvcb");
5622 cmd = (struct qeth_ipa_cmd *) data;
5623 if (cmd->hdr.return_code) {
5624 PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
5625 "Continuing\n",cmd->data.setdelvlan.vlan_id,
5626 QETH_CARD_IFNAME(card), cmd->hdr.return_code);
5627 QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
5628 QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
5629 QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
5630 }
5631 return 0;
5632}
5633
5634static int
5635qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
5636 enum qeth_ipa_cmds ipacmd)
5637{
5638 struct qeth_ipa_cmd *cmd;
5639 struct qeth_cmd_buffer *iob;
5640
5641 QETH_DBF_TEXT_(trace, 4, "L2sdv%x",ipacmd);
5642 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
5643 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
5644 cmd->data.setdelvlan.vlan_id = i;
5645 return qeth_send_ipa_cmd(card, iob,
5646 qeth_layer2_send_setdelvlan_cb, NULL);
5647}
5648
5649static void
5650qeth_layer2_process_vlans(struct qeth_card *card, int clear)
5651{
5652 unsigned short i;
5653
5654 QETH_DBF_TEXT(trace, 3, "L2prcvln");
5655
5656 if (!card->vlangrp)
5657 return;
5658 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
5659 if (vlan_group_get_device(card->vlangrp, i) == NULL)
5660 continue;
5661 if (clear)
5662 qeth_layer2_send_setdelvlan(card, i, IPA_CMD_DELVLAN);
5663 else
5664 qeth_layer2_send_setdelvlan(card, i, IPA_CMD_SETVLAN);
5665 }
5666}
5667
5668/*add_vid is layer 2 used only ....*/
5669static void
5670qeth_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
5671{
5672 struct qeth_card *card;
5673
5674 QETH_DBF_TEXT_(trace, 4, "aid:%d", vid);
5675
5676 card = (struct qeth_card *) dev->priv;
5677 if (!card->options.layer2)
5678 return;
5679 qeth_layer2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN);
5680}
5681
5682/*... kill_vid used for both modes*/
5683static void
5684qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
5685{
5686 struct qeth_card *card;
5687 unsigned long flags;
5688
5689 QETH_DBF_TEXT_(trace, 4, "kid:%d", vid);
5690
5691 card = (struct qeth_card *) dev->priv;
5692 /* free all skbs for the vlan device */
5693 qeth_free_vlan_skbs(card, vid);
5694 spin_lock_irqsave(&card->vlanlock, flags);
5695 /* unregister IP addresses of vlan device */
5696 qeth_free_vlan_addresses(card, vid);
5697 vlan_group_set_device(card->vlangrp, vid, NULL);
5698 spin_unlock_irqrestore(&card->vlanlock, flags);
5699 if (card->options.layer2)
5700 qeth_layer2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
5701 qeth_set_multicast_list(card->dev);
5702}
5703#endif
5704/**
5705 * Examine hardware response to SET_PROMISC_MODE
5706 */
5707static int
5708qeth_setadp_promisc_mode_cb(struct qeth_card *card,
5709 struct qeth_reply *reply,
5710 unsigned long data)
5711{
5712 struct qeth_ipa_cmd *cmd;
5713 struct qeth_ipacmd_setadpparms *setparms;
5714
5715 QETH_DBF_TEXT(trace,4,"prmadpcb");
5716
5717 cmd = (struct qeth_ipa_cmd *) data;
5718 setparms = &(cmd->data.setadapterparms);
5719
5720 qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
5721 if (cmd->hdr.return_code) {
5722 QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
5723 setparms->data.mode = SET_PROMISC_MODE_OFF;
5724 }
5725 card->info.promisc_mode = setparms->data.mode;
5726 return 0;
5727}
5728/*
5729 * Set promiscuous mode (on or off) (SET_PROMISC_MODE command)
5730 */
5731static void
5732qeth_setadp_promisc_mode(struct qeth_card *card)
5733{
5734 enum qeth_ipa_promisc_modes mode;
5735 struct net_device *dev = card->dev;
5736 struct qeth_cmd_buffer *iob;
5737 struct qeth_ipa_cmd *cmd;
5738
5739 QETH_DBF_TEXT(trace, 4, "setprom");
5740
5741 if (((dev->flags & IFF_PROMISC) &&
5742 (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
5743 (!(dev->flags & IFF_PROMISC) &&
5744 (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
5745 return;
5746 mode = SET_PROMISC_MODE_OFF;
5747 if (dev->flags & IFF_PROMISC)
5748 mode = SET_PROMISC_MODE_ON;
5749 QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);
5750
5751 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
5752 sizeof(struct qeth_ipacmd_setadpparms));
5753 cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
5754 cmd->data.setadapterparms.data.mode = mode;
5755 qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
5756}
5757
5758/**
5759 * set multicast address on card
5760 */
5761static void
5762qeth_set_multicast_list(struct net_device *dev)
5763{
5764 struct qeth_card *card = (struct qeth_card *) dev->priv;
5765
5766 if (card->info.type == QETH_CARD_TYPE_OSN)
5767 return ;
5768
5769 QETH_DBF_TEXT(trace, 3, "setmulti");
5770 qeth_delete_mc_addresses(card);
5771 if (card->options.layer2) {
5772 qeth_layer2_add_multicast(card);
5773 goto out;
5774 }
5775 qeth_add_multicast_ipv4(card);
5776#ifdef CONFIG_QETH_IPV6
5777 qeth_add_multicast_ipv6(card);
5778#endif
5779out:
5780 qeth_set_ip_addr_list(card);
5781 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
5782 return;
5783 qeth_setadp_promisc_mode(card);
5784}
5785
5786static int
5787qeth_neigh_setup(struct net_device *dev, struct neigh_parms *np)
5788{
5789 return 0;
5790}
5791
5792static void
5793qeth_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
5794{
5795 if (dev->type == ARPHRD_IEEE802_TR)
5796 ip_tr_mc_map(ipm, mac);
5797 else
5798 ip_eth_mc_map(ipm, mac);
5799}
5800
5801static struct qeth_ipaddr *
5802qeth_get_addr_buffer(enum qeth_prot_versions prot)
5803{
5804 struct qeth_ipaddr *addr;
5805
5806 addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
5807 if (addr == NULL) {
5808 PRINT_WARN("Not enough memory to add address\n");
5809 return NULL;
5810 }
5811 addr->type = QETH_IP_TYPE_NORMAL;
5812 addr->proto = prot;
5813 return addr;
5814}
5815
5816int
5817qeth_osn_assist(struct net_device *dev,
5818 void *data,
5819 int data_len)
5820{
5821 struct qeth_cmd_buffer *iob;
5822 struct qeth_card *card;
5823 int rc;
5824
5825 QETH_DBF_TEXT(trace, 2, "osnsdmc");
5826 if (!dev)
5827 return -ENODEV;
5828 card = (struct qeth_card *)dev->priv;
5829 if (!card)
5830 return -ENODEV;
5831 if ((card->state != CARD_STATE_UP) &&
5832 (card->state != CARD_STATE_SOFTSETUP))
5833 return -ENODEV;
5834 iob = qeth_wait_for_buffer(&card->write);
5835 memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
5836 rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
5837 return rc;
5838}
5839
5840static struct net_device *
5841qeth_netdev_by_devno(unsigned char *read_dev_no)
5842{
5843 struct qeth_card *card;
5844 struct net_device *ndev;
5845 unsigned char *readno;
5846 __u16 temp_dev_no, card_dev_no;
5847 char *endp;
5848 unsigned long flags;
5849
5850 ndev = NULL;
5851 memcpy(&temp_dev_no, read_dev_no, 2);
5852 read_lock_irqsave(&qeth_card_list.rwlock, flags);
5853 list_for_each_entry(card, &qeth_card_list.list, list) {
5854 readno = CARD_RDEV_ID(card);
5855 readno += (strlen(readno) - 4);
5856 card_dev_no = simple_strtoul(readno, &endp, 16);
5857 if (card_dev_no == temp_dev_no) {
5858 ndev = card->dev;
5859 break;
5860 }
5861 }
5862 read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
5863 return ndev;
5864}
5865
5866int
5867qeth_osn_register(unsigned char *read_dev_no,
5868 struct net_device **dev,
5869 int (*assist_cb)(struct net_device *, void *),
5870 int (*data_cb)(struct sk_buff *))
5871{
5872 struct qeth_card * card;
5873
5874 QETH_DBF_TEXT(trace, 2, "osnreg");
5875 *dev = qeth_netdev_by_devno(read_dev_no);
5876 if (*dev == NULL)
5877 return -ENODEV;
5878 card = (struct qeth_card *)(*dev)->priv;
5879 if (!card)
5880 return -ENODEV;
5881 if ((assist_cb == NULL) || (data_cb == NULL))
5882 return -EINVAL;
5883 card->osn_info.assist_cb = assist_cb;
5884 card->osn_info.data_cb = data_cb;
5885 return 0;
5886}
5887
5888void
5889qeth_osn_deregister(struct net_device * dev)
5890{
5891 struct qeth_card *card;
5892
5893 QETH_DBF_TEXT(trace, 2, "osndereg");
5894 if (!dev)
5895 return;
5896 card = (struct qeth_card *)dev->priv;
5897 if (!card)
5898 return;
5899 card->osn_info.assist_cb = NULL;
5900 card->osn_info.data_cb = NULL;
5901 return;
5902}
5903
5904static void
5905qeth_delete_mc_addresses(struct qeth_card *card)
5906{
5907 struct qeth_ipaddr *iptodo;
5908 unsigned long flags;
5909
5910 QETH_DBF_TEXT(trace,4,"delmc");
5911 iptodo = qeth_get_addr_buffer(QETH_PROT_IPV4);
5912 if (!iptodo) {
5913 QETH_DBF_TEXT(trace, 2, "dmcnomem");
5914 return;
5915 }
5916 iptodo->type = QETH_IP_TYPE_DEL_ALL_MC;
5917 spin_lock_irqsave(&card->ip_lock, flags);
5918 if (!__qeth_insert_ip_todo(card, iptodo, 0))
5919 kfree(iptodo);
5920 spin_unlock_irqrestore(&card->ip_lock, flags);
5921}
5922
5923static void
5924qeth_add_mc(struct qeth_card *card, struct in_device *in4_dev)
5925{
5926 struct qeth_ipaddr *ipm;
5927 struct ip_mc_list *im4;
5928 char buf[MAX_ADDR_LEN];
5929
5930 QETH_DBF_TEXT(trace,4,"addmc");
5931 for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
5932 qeth_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev);
5933 ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
5934 if (!ipm)
5935 continue;
5936 ipm->u.a4.addr = im4->multiaddr;
5937 memcpy(ipm->mac,buf,OSA_ADDR_LEN);
5938 ipm->is_multicast = 1;
5939 if (!qeth_add_ip(card,ipm))
5940 kfree(ipm);
5941 }
5942}
5943
5944static inline void
5945qeth_add_vlan_mc(struct qeth_card *card)
5946{
5947#ifdef CONFIG_QETH_VLAN
5948 struct in_device *in_dev;
5949 struct vlan_group *vg;
5950 int i;
5951
5952 QETH_DBF_TEXT(trace,4,"addmcvl");
5953 if ( ((card->options.layer2 == 0) &&
5954 (!qeth_is_supported(card,IPA_FULL_VLAN))) ||
5955 (card->vlangrp == NULL) )
5956 return ;
5957
5958 vg = card->vlangrp;
5959 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
5960 struct net_device *netdev = vlan_group_get_device(vg, i);
5961 if (netdev == NULL ||
5962 !(netdev->flags & IFF_UP))
5963 continue;
5964 in_dev = in_dev_get(netdev);
5965 if (!in_dev)
5966 continue;
5967 read_lock(&in_dev->mc_list_lock);
5968 qeth_add_mc(card,in_dev);
5969 read_unlock(&in_dev->mc_list_lock);
5970 in_dev_put(in_dev);
5971 }
5972#endif
5973}
5974
5975static void
5976qeth_add_multicast_ipv4(struct qeth_card *card)
5977{
5978 struct in_device *in4_dev;
5979
5980 QETH_DBF_TEXT(trace,4,"chkmcv4");
5981 in4_dev = in_dev_get(card->dev);
5982 if (in4_dev == NULL)
5983 return;
5984 read_lock(&in4_dev->mc_list_lock);
5985 qeth_add_mc(card, in4_dev);
5986 qeth_add_vlan_mc(card);
5987 read_unlock(&in4_dev->mc_list_lock);
5988 in_dev_put(in4_dev);
5989}
5990
5991static void
5992qeth_layer2_add_multicast(struct qeth_card *card)
5993{
5994 struct qeth_ipaddr *ipm;
5995 struct dev_mc_list *dm;
5996
5997 QETH_DBF_TEXT(trace,4,"L2addmc");
5998 for (dm = card->dev->mc_list; dm; dm = dm->next) {
5999 ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
6000 if (!ipm)
6001 continue;
6002 memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN);
6003 ipm->is_multicast = 1;
6004 if (!qeth_add_ip(card, ipm))
6005 kfree(ipm);
6006 }
6007}
6008
6009#ifdef CONFIG_QETH_IPV6
6010static void
6011qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
6012{
6013 struct qeth_ipaddr *ipm;
6014 struct ifmcaddr6 *im6;
6015 char buf[MAX_ADDR_LEN];
6016
6017 QETH_DBF_TEXT(trace,4,"addmc6");
6018 for (im6 = in6_dev->mc_list; im6 != NULL; im6 = im6->next) {
6019 ndisc_mc_map(&im6->mca_addr, buf, in6_dev->dev, 0);
6020 ipm = qeth_get_addr_buffer(QETH_PROT_IPV6);
6021 if (!ipm)
6022 continue;
6023 ipm->is_multicast = 1;
6024 memcpy(ipm->mac,buf,OSA_ADDR_LEN);
6025 memcpy(&ipm->u.a6.addr,&im6->mca_addr.s6_addr,
6026 sizeof(struct in6_addr));
6027 if (!qeth_add_ip(card,ipm))
6028 kfree(ipm);
6029 }
6030}
6031
6032static inline void
6033qeth_add_vlan_mc6(struct qeth_card *card)
6034{
6035#ifdef CONFIG_QETH_VLAN
6036 struct inet6_dev *in_dev;
6037 struct vlan_group *vg;
6038 int i;
6039
6040 QETH_DBF_TEXT(trace,4,"admc6vl");
6041 if ( ((card->options.layer2 == 0) &&
6042 (!qeth_is_supported(card,IPA_FULL_VLAN))) ||
6043 (card->vlangrp == NULL))
6044 return ;
6045
6046 vg = card->vlangrp;
6047 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
6048 struct net_device *netdev = vlan_group_get_device(vg, i);
6049 if (netdev == NULL ||
6050 !(netdev->flags & IFF_UP))
6051 continue;
6052 in_dev = in6_dev_get(netdev);
6053 if (!in_dev)
6054 continue;
6055 read_lock_bh(&in_dev->lock);
6056 qeth_add_mc6(card,in_dev);
6057 read_unlock_bh(&in_dev->lock);
6058 in6_dev_put(in_dev);
6059 }
6060#endif /* CONFIG_QETH_VLAN */
6061}
6062
6063static void
6064qeth_add_multicast_ipv6(struct qeth_card *card)
6065{
6066 struct inet6_dev *in6_dev;
6067
6068 QETH_DBF_TEXT(trace,4,"chkmcv6");
6069 if (!qeth_is_supported(card, IPA_IPV6))
6070 return ;
6071 in6_dev = in6_dev_get(card->dev);
6072 if (in6_dev == NULL)
6073 return;
6074 read_lock_bh(&in6_dev->lock);
6075 qeth_add_mc6(card, in6_dev);
6076 qeth_add_vlan_mc6(card);
6077 read_unlock_bh(&in6_dev->lock);
6078 in6_dev_put(in6_dev);
6079}
6080#endif /* CONFIG_QETH_IPV6 */
6081
6082static int
6083qeth_layer2_send_setdelmac(struct qeth_card *card, __u8 *mac,
6084 enum qeth_ipa_cmds ipacmd,
6085 int (*reply_cb) (struct qeth_card *,
6086 struct qeth_reply*,
6087 unsigned long))
6088{
6089 struct qeth_ipa_cmd *cmd;
6090 struct qeth_cmd_buffer *iob;
6091
6092 QETH_DBF_TEXT(trace, 2, "L2sdmac");
6093 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
6094 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
6095 cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
6096 memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
6097 return qeth_send_ipa_cmd(card, iob, reply_cb, NULL);
6098}
6099
6100static int
6101qeth_layer2_send_setgroupmac_cb(struct qeth_card *card,
6102 struct qeth_reply *reply,
6103 unsigned long data)
6104{
6105 struct qeth_ipa_cmd *cmd;
6106 __u8 *mac;
6107
6108 QETH_DBF_TEXT(trace, 2, "L2Sgmacb");
6109 cmd = (struct qeth_ipa_cmd *) data;
6110 mac = &cmd->data.setdelmac.mac[0];
6111 /* MAC already registered, needed in couple/uncouple case */
6112 if (cmd->hdr.return_code == 0x2005) {
6113 PRINT_WARN("Group MAC %02x:%02x:%02x:%02x:%02x:%02x " \
6114 "already existing on %s \n",
6115 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
6116 QETH_CARD_IFNAME(card));
6117 cmd->hdr.return_code = 0;
6118 }
6119 if (cmd->hdr.return_code)
6120 PRINT_ERR("Could not set group MAC " \
6121 "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
6122 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
6123 QETH_CARD_IFNAME(card),cmd->hdr.return_code);
6124 return 0;
6125}
6126
6127static int
6128qeth_layer2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
6129{
6130 QETH_DBF_TEXT(trace, 2, "L2Sgmac");
6131 return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_SETGMAC,
6132 qeth_layer2_send_setgroupmac_cb);
6133}
6134
6135static int
6136qeth_layer2_send_delgroupmac_cb(struct qeth_card *card,
6137 struct qeth_reply *reply,
6138 unsigned long data)
6139{
6140 struct qeth_ipa_cmd *cmd;
6141 __u8 *mac;
6142
6143 QETH_DBF_TEXT(trace, 2, "L2Dgmacb");
6144 cmd = (struct qeth_ipa_cmd *) data;
6145 mac = &cmd->data.setdelmac.mac[0];
6146 if (cmd->hdr.return_code)
6147 PRINT_ERR("Could not delete group MAC " \
6148 "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
6149 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
6150 QETH_CARD_IFNAME(card), cmd->hdr.return_code);
6151 return 0;
6152}
6153
6154static int
6155qeth_layer2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
6156{
6157 QETH_DBF_TEXT(trace, 2, "L2Dgmac");
6158 return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELGMAC,
6159 qeth_layer2_send_delgroupmac_cb);
6160}
6161
6162static int
6163qeth_layer2_send_setmac_cb(struct qeth_card *card,
6164 struct qeth_reply *reply,
6165 unsigned long data)
6166{
6167 struct qeth_ipa_cmd *cmd;
6168
6169 QETH_DBF_TEXT(trace, 2, "L2Smaccb");
6170 cmd = (struct qeth_ipa_cmd *) data;
6171 if (cmd->hdr.return_code) {
6172 QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code);
6173 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
6174 cmd->hdr.return_code = -EIO;
6175 } else {
6176 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
6177 memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac,
6178 OSA_ADDR_LEN);
6179 PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
6180 "successfully registered on device %s\n",
6181 card->dev->dev_addr[0], card->dev->dev_addr[1],
6182 card->dev->dev_addr[2], card->dev->dev_addr[3],
6183 card->dev->dev_addr[4], card->dev->dev_addr[5],
6184 card->dev->name);
6185 }
6186 return 0;
6187}
6188
6189static int
6190qeth_layer2_send_setmac(struct qeth_card *card, __u8 *mac)
6191{
6192 QETH_DBF_TEXT(trace, 2, "L2Setmac");
6193 return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
6194 qeth_layer2_send_setmac_cb);
6195}
6196
6197static int
6198qeth_layer2_send_delmac_cb(struct qeth_card *card,
6199 struct qeth_reply *reply,
6200 unsigned long data)
6201{
6202 struct qeth_ipa_cmd *cmd;
6203
6204 QETH_DBF_TEXT(trace, 2, "L2Dmaccb");
6205 cmd = (struct qeth_ipa_cmd *) data;
6206 if (cmd->hdr.return_code) {
6207 QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
6208 cmd->hdr.return_code = -EIO;
6209 return 0;
6210 }
6211 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
6212
6213 return 0;
6214}
6215static int
6216qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac)
6217{
6218 QETH_DBF_TEXT(trace, 2, "L2Delmac");
6219 if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
6220 return 0;
6221 return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
6222 qeth_layer2_send_delmac_cb);
6223}
6224
6225static int
6226qeth_layer2_set_mac_address(struct net_device *dev, void *p)
6227{
6228 struct sockaddr *addr = p;
6229 struct qeth_card *card;
6230 int rc = 0;
6231
6232 QETH_DBF_TEXT(trace, 3, "setmac");
6233
6234 if (qeth_verify_dev(dev) != QETH_REAL_CARD) {
6235 QETH_DBF_TEXT(trace, 3, "setmcINV");
6236 return -EOPNOTSUPP;
6237 }
6238 card = (struct qeth_card *) dev->priv;
6239
6240 if (!card->options.layer2) {
6241 PRINT_WARN("Setting MAC address on %s is not supported "
6242 "in Layer 3 mode.\n", dev->name);
6243 QETH_DBF_TEXT(trace, 3, "setmcLY3");
6244 return -EOPNOTSUPP;
6245 }
6246 if (card->info.type == QETH_CARD_TYPE_OSN) {
6247 PRINT_WARN("Setting MAC address on %s is not supported.\n",
6248 dev->name);
6249 QETH_DBF_TEXT(trace, 3, "setmcOSN");
6250 return -EOPNOTSUPP;
6251 }
6252 QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
6253 QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
6254 rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]);
6255 if (!rc)
6256 rc = qeth_layer2_send_setmac(card, addr->sa_data);
6257 return rc;
6258}
6259
6260static void
6261qeth_fill_ipacmd_header(struct qeth_card *card, struct qeth_ipa_cmd *cmd,
6262 __u8 command, enum qeth_prot_versions prot)
6263{
6264 memset(cmd, 0, sizeof (struct qeth_ipa_cmd));
6265 cmd->hdr.command = command;
6266 cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST;
6267 cmd->hdr.seqno = card->seqno.ipa;
6268 cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type);
6269 cmd->hdr.rel_adapter_no = (__u8) card->info.portno;
6270 if (card->options.layer2)
6271 cmd->hdr.prim_version_no = 2;
6272 else
6273 cmd->hdr.prim_version_no = 1;
6274 cmd->hdr.param_count = 1;
6275 cmd->hdr.prot_version = prot;
6276 cmd->hdr.ipa_supported = 0;
6277 cmd->hdr.ipa_enabled = 0;
6278}
6279
6280static struct qeth_cmd_buffer *
6281qeth_get_ipacmd_buffer(struct qeth_card *card, enum qeth_ipa_cmds ipacmd,
6282 enum qeth_prot_versions prot)
6283{
6284 struct qeth_cmd_buffer *iob;
6285 struct qeth_ipa_cmd *cmd;
6286
6287 iob = qeth_wait_for_buffer(&card->write);
6288 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
6289 qeth_fill_ipacmd_header(card, cmd, ipacmd, prot);
6290
6291 return iob;
6292}
6293
6294static int
6295qeth_send_setdelmc(struct qeth_card *card, struct qeth_ipaddr *addr, int ipacmd)
6296{
6297 int rc;
6298 struct qeth_cmd_buffer *iob;
6299 struct qeth_ipa_cmd *cmd;
6300
6301 QETH_DBF_TEXT(trace,4,"setdelmc");
6302
6303 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
6304 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
6305 memcpy(&cmd->data.setdelipm.mac,addr->mac, OSA_ADDR_LEN);
6306 if (addr->proto == QETH_PROT_IPV6)
6307 memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr,
6308 sizeof(struct in6_addr));
6309 else
6310 memcpy(&cmd->data.setdelipm.ip4, &addr->u.a4.addr,4);
6311
6312 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
6313
6314 return rc;
6315}
6316static void
6317qeth_fill_netmask(u8 *netmask, unsigned int len)
6318{
6319 int i,j;
6320 for (i=0;i<16;i++) {
6321 j=(len)-(i*8);
6322 if (j >= 8)
6323 netmask[i] = 0xff;
6324 else if (j > 0)
6325 netmask[i] = (u8)(0xFF00>>j);
6326 else
6327 netmask[i] = 0;
6328 }
6329}
6330
6331static int
6332qeth_send_setdelip(struct qeth_card *card, struct qeth_ipaddr *addr,
6333 int ipacmd, unsigned int flags)
6334{
6335 int rc;
6336 struct qeth_cmd_buffer *iob;
6337 struct qeth_ipa_cmd *cmd;
6338 __u8 netmask[16];
6339
6340 QETH_DBF_TEXT(trace,4,"setdelip");
6341 QETH_DBF_TEXT_(trace,4,"flags%02X", flags);
6342
6343 iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
6344 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
6345 if (addr->proto == QETH_PROT_IPV6) {
6346 memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr,
6347 sizeof(struct in6_addr));
6348 qeth_fill_netmask(netmask,addr->u.a6.pfxlen);
6349 memcpy(cmd->data.setdelip6.mask, netmask,
6350 sizeof(struct in6_addr));
6351 cmd->data.setdelip6.flags = flags;
6352 } else {
6353 memcpy(cmd->data.setdelip4.ip_addr, &addr->u.a4.addr, 4);
6354 memcpy(cmd->data.setdelip4.mask, &addr->u.a4.mask, 4);
6355 cmd->data.setdelip4.flags = flags;
6356 }
6357
6358 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
6359
6360 return rc;
6361}
6362
6363static int
6364qeth_layer2_register_addr_entry(struct qeth_card *card,
6365 struct qeth_ipaddr *addr)
6366{
6367 if (!addr->is_multicast)
6368 return 0;
6369 QETH_DBF_TEXT(trace, 2, "setgmac");
6370 QETH_DBF_HEX(trace,3,&addr->mac[0],OSA_ADDR_LEN);
6371 return qeth_layer2_send_setgroupmac(card, &addr->mac[0]);
6372}
6373
6374static int
6375qeth_layer2_deregister_addr_entry(struct qeth_card *card,
6376 struct qeth_ipaddr *addr)
6377{
6378 if (!addr->is_multicast)
6379 return 0;
6380 QETH_DBF_TEXT(trace, 2, "delgmac");
6381 QETH_DBF_HEX(trace,3,&addr->mac[0],OSA_ADDR_LEN);
6382 return qeth_layer2_send_delgroupmac(card, &addr->mac[0]);
6383}
6384
6385static int
6386qeth_layer3_register_addr_entry(struct qeth_card *card,
6387 struct qeth_ipaddr *addr)
6388{
6389 char buf[50];
6390 int rc;
6391 int cnt = 3;
6392
6393 if (addr->proto == QETH_PROT_IPV4) {
6394 QETH_DBF_TEXT(trace, 2,"setaddr4");
6395 QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
6396 } else if (addr->proto == QETH_PROT_IPV6) {
6397 QETH_DBF_TEXT(trace, 2, "setaddr6");
6398 QETH_DBF_HEX(trace,3,&addr->u.a6.addr,8);
6399 QETH_DBF_HEX(trace,3,((char *)&addr->u.a6.addr)+8,8);
6400 } else {
6401 QETH_DBF_TEXT(trace, 2, "setaddr?");
6402 QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
6403 }
6404 do {
6405 if (addr->is_multicast)
6406 rc = qeth_send_setdelmc(card, addr, IPA_CMD_SETIPM);
6407 else
6408 rc = qeth_send_setdelip(card, addr, IPA_CMD_SETIP,
6409 addr->set_flags);
6410 if (rc)
6411 QETH_DBF_TEXT(trace, 2, "failed");
6412 } while ((--cnt > 0) && rc);
6413 if (rc){
6414 QETH_DBF_TEXT(trace, 2, "FAILED");
6415 qeth_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf);
6416 PRINT_WARN("Could not register IP address %s (rc=0x%x/%d)\n",
6417 buf, rc, rc);
6418 }
6419 return rc;
6420}
6421
6422static int
6423qeth_layer3_deregister_addr_entry(struct qeth_card *card,
6424 struct qeth_ipaddr *addr)
6425{
6426 //char buf[50];
6427 int rc;
6428
6429 if (addr->proto == QETH_PROT_IPV4) {
6430 QETH_DBF_TEXT(trace, 2,"deladdr4");
6431 QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
6432 } else if (addr->proto == QETH_PROT_IPV6) {
6433 QETH_DBF_TEXT(trace, 2, "deladdr6");
6434 QETH_DBF_HEX(trace,3,&addr->u.a6.addr,8);
6435 QETH_DBF_HEX(trace,3,((char *)&addr->u.a6.addr)+8,8);
6436 } else {
6437 QETH_DBF_TEXT(trace, 2, "deladdr?");
6438 QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
6439 }
6440 if (addr->is_multicast)
6441 rc = qeth_send_setdelmc(card, addr, IPA_CMD_DELIPM);
6442 else
6443 rc = qeth_send_setdelip(card, addr, IPA_CMD_DELIP,
6444 addr->del_flags);
6445 if (rc) {
6446 QETH_DBF_TEXT(trace, 2, "failed");
6447 /* TODO: re-activate this warning as soon as we have a
6448 * clean mirco code
6449 qeth_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf);
6450 PRINT_WARN("Could not deregister IP address %s (rc=%x)\n",
6451 buf, rc);
6452 */
6453 }
6454 return rc;
6455}
6456
6457static int
6458qeth_register_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
6459{
6460 if (card->options.layer2)
6461 return qeth_layer2_register_addr_entry(card, addr);
6462
6463 return qeth_layer3_register_addr_entry(card, addr);
6464}
6465
6466static int
6467qeth_deregister_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
6468{
6469 if (card->options.layer2)
6470 return qeth_layer2_deregister_addr_entry(card, addr);
6471
6472 return qeth_layer3_deregister_addr_entry(card, addr);
6473}
6474
6475static u32
6476qeth_ethtool_get_tx_csum(struct net_device *dev)
6477{
6478 return (dev->features & NETIF_F_HW_CSUM) != 0;
6479}
6480
6481static int
6482qeth_ethtool_set_tx_csum(struct net_device *dev, u32 data)
6483{
6484 if (data)
6485 dev->features |= NETIF_F_HW_CSUM;
6486 else
6487 dev->features &= ~NETIF_F_HW_CSUM;
6488
6489 return 0;
6490}
6491
6492static u32
6493qeth_ethtool_get_rx_csum(struct net_device *dev)
6494{
6495 struct qeth_card *card = (struct qeth_card *)dev->priv;
6496
6497 return (card->options.checksum_type == HW_CHECKSUMMING);
6498}
6499
6500static int
6501qeth_ethtool_set_rx_csum(struct net_device *dev, u32 data)
6502{
6503 struct qeth_card *card = (struct qeth_card *)dev->priv;
6504
6505 if ((card->state != CARD_STATE_DOWN) &&
6506 (card->state != CARD_STATE_RECOVER))
6507 return -EPERM;
6508 if (data)
6509 card->options.checksum_type = HW_CHECKSUMMING;
6510 else
6511 card->options.checksum_type = SW_CHECKSUMMING;
6512 return 0;
6513}
6514
6515static u32
6516qeth_ethtool_get_sg(struct net_device *dev)
6517{
6518 struct qeth_card *card = (struct qeth_card *)dev->priv;
6519
6520 return ((card->options.large_send != QETH_LARGE_SEND_NO) &&
6521 (dev->features & NETIF_F_SG));
6522}
6523
6524static int
6525qeth_ethtool_set_sg(struct net_device *dev, u32 data)
6526{
6527 struct qeth_card *card = (struct qeth_card *)dev->priv;
6528
6529 if (data) {
6530 if (card->options.large_send != QETH_LARGE_SEND_NO)
6531 dev->features |= NETIF_F_SG;
6532 else {
6533 dev->features &= ~NETIF_F_SG;
6534 return -EINVAL;
6535 }
6536 } else
6537 dev->features &= ~NETIF_F_SG;
6538 return 0;
6539}
6540
6541static u32
6542qeth_ethtool_get_tso(struct net_device *dev)
6543{
6544 struct qeth_card *card = (struct qeth_card *)dev->priv;
6545
6546 return ((card->options.large_send != QETH_LARGE_SEND_NO) &&
6547 (dev->features & NETIF_F_TSO));
6548}
6549
6550static int
6551qeth_ethtool_set_tso(struct net_device *dev, u32 data)
6552{
6553 struct qeth_card *card = (struct qeth_card *)dev->priv;
6554
6555 if (data) {
6556 if (card->options.large_send != QETH_LARGE_SEND_NO)
6557 dev->features |= NETIF_F_TSO;
6558 else {
6559 dev->features &= ~NETIF_F_TSO;
6560 return -EINVAL;
6561 }
6562 } else
6563 dev->features &= ~NETIF_F_TSO;
6564 return 0;
6565}
6566
6567static struct ethtool_ops qeth_ethtool_ops = {
6568 .get_tx_csum = qeth_ethtool_get_tx_csum,
6569 .set_tx_csum = qeth_ethtool_set_tx_csum,
6570 .get_rx_csum = qeth_ethtool_get_rx_csum,
6571 .set_rx_csum = qeth_ethtool_set_rx_csum,
6572 .get_sg = qeth_ethtool_get_sg,
6573 .set_sg = qeth_ethtool_set_sg,
6574 .get_tso = qeth_ethtool_get_tso,
6575 .set_tso = qeth_ethtool_set_tso,
6576};
6577
6578static int
6579qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr)
6580{
6581 const struct qeth_card *card;
6582 const struct ethhdr *eth;
6583 struct net_device *dev = skb->dev;
6584
6585 if (dev->type != ARPHRD_IEEE802_TR)
6586 return 0;
6587
6588 card = qeth_get_card_from_dev(dev);
6589 if (card->options.layer2)
6590 goto haveheader;
6591#ifdef CONFIG_QETH_IPV6
6592 /* cause of the manipulated arp constructor and the ARP
6593 flag for OSAE devices we have some nasty exceptions */
6594 if (card->info.type == QETH_CARD_TYPE_OSAE) {
6595 if (!card->options.fake_ll) {
6596 if ((skb->pkt_type==PACKET_OUTGOING) &&
6597 (skb->protocol==ETH_P_IPV6))
6598 goto haveheader;
6599 else
6600 return 0;
6601 } else {
6602 if ((skb->pkt_type==PACKET_OUTGOING) &&
6603 (skb->protocol==ETH_P_IP))
6604 return 0;
6605 else
6606 goto haveheader;
6607 }
6608 }
6609#endif
6610 if (!card->options.fake_ll)
6611 return 0;
6612haveheader:
6613 eth = eth_hdr(skb);
6614 memcpy(haddr, eth->h_source, ETH_ALEN);
6615 return ETH_ALEN;
6616}
6617
6618static const struct header_ops qeth_null_ops = {
6619 .parse = qeth_hard_header_parse,
6620};
6621
6622static int
6623qeth_netdev_init(struct net_device *dev)
6624{
6625 struct qeth_card *card;
6626
6627 card = (struct qeth_card *) dev->priv;
6628
6629 QETH_DBF_TEXT(trace,3,"initdev");
6630
6631 dev->tx_timeout = &qeth_tx_timeout;
6632 dev->watchdog_timeo = QETH_TX_TIMEOUT;
6633 dev->open = qeth_open;
6634 dev->stop = qeth_stop;
6635 dev->hard_start_xmit = qeth_hard_start_xmit;
6636 dev->do_ioctl = qeth_do_ioctl;
6637 dev->get_stats = qeth_get_stats;
6638 dev->change_mtu = qeth_change_mtu;
6639 dev->neigh_setup = qeth_neigh_setup;
6640 dev->set_multicast_list = qeth_set_multicast_list;
6641#ifdef CONFIG_QETH_VLAN
6642 dev->vlan_rx_register = qeth_vlan_rx_register;
6643 dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
6644 dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
6645#endif
6646 if (qeth_get_netdev_flags(card) & IFF_NOARP)
6647 dev->header_ops = &qeth_null_ops;
6648
6649#ifdef CONFIG_QETH_IPV6
6650 /*IPv6 address autoconfiguration stuff*/
6651 if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
6652 card->dev->dev_id = card->info.unique_id & 0xffff;
6653#endif
6654 if (card->options.fake_ll &&
6655 (qeth_get_netdev_flags(card) & IFF_NOARP))
6656 dev->header_ops = &qeth_fake_ops;
6657
6658 dev->set_mac_address = qeth_layer2_set_mac_address;
6659 dev->flags |= qeth_get_netdev_flags(card);
6660 if ((card->options.fake_broadcast) ||
6661 (card->info.broadcast_capable))
6662 dev->flags |= IFF_BROADCAST;
6663 dev->hard_header_len =
6664 qeth_get_hlen(card->info.link_type) + card->options.add_hhlen;
6665 dev->addr_len = OSA_ADDR_LEN;
6666 dev->mtu = card->info.initial_mtu;
6667 if (card->info.type != QETH_CARD_TYPE_OSN)
6668 SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
6669 return 0;
6670}
6671
6672static void
6673qeth_init_func_level(struct qeth_card *card)
6674{
6675 if (card->ipato.enabled) {
6676 if (card->info.type == QETH_CARD_TYPE_IQD)
6677 card->info.func_level =
6678 QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT;
6679 else
6680 card->info.func_level =
6681 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
6682 } else {
6683 if (card->info.type == QETH_CARD_TYPE_IQD)
6684 /*FIXME:why do we have same values for dis and ena for osae??? */
6685 card->info.func_level =
6686 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
6687 else
6688 card->info.func_level =
6689 QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT;
6690 }
6691}
6692
6693/**
6694 * hardsetup card, initialize MPC and QDIO stuff
6695 */
6696static int
6697qeth_hardsetup_card(struct qeth_card *card)
6698{
6699 int retries = 3;
6700 int rc;
6701
6702 QETH_DBF_TEXT(setup, 2, "hrdsetup");
6703
6704 atomic_set(&card->force_alloc_skb, 0);
6705retry:
6706 if (retries < 3){
6707 PRINT_WARN("Retrying to do IDX activates.\n");
6708 ccw_device_set_offline(CARD_DDEV(card));
6709 ccw_device_set_offline(CARD_WDEV(card));
6710 ccw_device_set_offline(CARD_RDEV(card));
6711 ccw_device_set_online(CARD_RDEV(card));
6712 ccw_device_set_online(CARD_WDEV(card));
6713 ccw_device_set_online(CARD_DDEV(card));
6714 }
6715 rc = qeth_qdio_clear_card(card,card->info.type!=QETH_CARD_TYPE_IQD);
6716 if (rc == -ERESTARTSYS) {
6717 QETH_DBF_TEXT(setup, 2, "break1");
6718 return rc;
6719 } else if (rc) {
6720 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
6721 if (--retries < 0)
6722 goto out;
6723 else
6724 goto retry;
6725 }
6726 if ((rc = qeth_get_unitaddr(card))){
6727 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
6728 return rc;
6729 }
6730 qeth_init_tokens(card);
6731 qeth_init_func_level(card);
6732 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
6733 if (rc == -ERESTARTSYS) {
6734 QETH_DBF_TEXT(setup, 2, "break2");
6735 return rc;
6736 } else if (rc) {
6737 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
6738 if (--retries < 0)
6739 goto out;
6740 else
6741 goto retry;
6742 }
6743 rc = qeth_idx_activate_channel(&card->write, qeth_idx_write_cb);
6744 if (rc == -ERESTARTSYS) {
6745 QETH_DBF_TEXT(setup, 2, "break3");
6746 return rc;
6747 } else if (rc) {
6748 QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
6749 if (--retries < 0)
6750 goto out;
6751 else
6752 goto retry;
6753 }
6754 if ((rc = qeth_mpc_initialize(card))){
6755 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
6756 goto out;
6757 }
6758 /*network device will be recovered*/
6759 if (card->dev) {
6760 card->dev->header_ops = card->orig_header_ops;
6761 if (card->options.fake_ll &&
6762 (qeth_get_netdev_flags(card) & IFF_NOARP))
6763 card->dev->header_ops = &qeth_fake_ops;
6764 return 0;
6765 }
6766 /* at first set_online allocate netdev */
6767 card->dev = qeth_get_netdevice(card->info.type,
6768 card->info.link_type);
6769 if (!card->dev){
6770 qeth_qdio_clear_card(card, card->info.type !=
6771 QETH_CARD_TYPE_IQD);
6772 rc = -ENODEV;
6773 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
6774 goto out;
6775 }
6776 card->dev->priv = card;
6777 card->orig_header_ops = card->dev->header_ops;
6778 card->dev->type = qeth_get_arphdr_type(card->info.type,
6779 card->info.link_type);
6780 card->dev->init = qeth_netdev_init;
6781 return 0;
6782out:
6783 PRINT_ERR("Initialization in hardsetup failed! rc=%d\n", rc);
6784 return rc;
6785}
6786
6787static int
6788qeth_default_setassparms_cb(struct qeth_card *card, struct qeth_reply *reply,
6789 unsigned long data)
6790{
6791 struct qeth_ipa_cmd *cmd;
6792
6793 QETH_DBF_TEXT(trace,4,"defadpcb");
6794
6795 cmd = (struct qeth_ipa_cmd *) data;
6796 if (cmd->hdr.return_code == 0){
6797 cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
6798 if (cmd->hdr.prot_version == QETH_PROT_IPV4)
6799 card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
6800#ifdef CONFIG_QETH_IPV6
6801 if (cmd->hdr.prot_version == QETH_PROT_IPV6)
6802 card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
6803#endif
6804 }
6805 if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM &&
6806 cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
6807 card->info.csum_mask = cmd->data.setassparms.data.flags_32bit;
6808 QETH_DBF_TEXT_(trace, 3, "csum:%d", card->info.csum_mask);
6809 }
6810 return 0;
6811}
6812
6813static int
6814qeth_default_setadapterparms_cb(struct qeth_card *card,
6815 struct qeth_reply *reply,
6816 unsigned long data)
6817{
6818 struct qeth_ipa_cmd *cmd;
6819
6820 QETH_DBF_TEXT(trace,4,"defadpcb");
6821
6822 cmd = (struct qeth_ipa_cmd *) data;
6823 if (cmd->hdr.return_code == 0)
6824 cmd->hdr.return_code = cmd->data.setadapterparms.hdr.return_code;
6825 return 0;
6826}
6827
6828
6829
6830static int
6831qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,
6832 unsigned long data)
6833{
6834 struct qeth_ipa_cmd *cmd;
6835
6836 QETH_DBF_TEXT(trace,3,"quyadpcb");
6837
6838 cmd = (struct qeth_ipa_cmd *) data;
6839 if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f)
6840 card->info.link_type =
6841 cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
6842 card->options.adp.supported_funcs =
6843 cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds;
6844 return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
6845}
6846
6847static int
6848qeth_query_setadapterparms(struct qeth_card *card)
6849{
6850 int rc;
6851 struct qeth_cmd_buffer *iob;
6852
6853 QETH_DBF_TEXT(trace,3,"queryadp");
6854 iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED,
6855 sizeof(struct qeth_ipacmd_setadpparms));
6856 rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL);
6857 return rc;
6858}
6859
6860static int
6861qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
6862 struct qeth_reply *reply,
6863 unsigned long data)
6864{
6865 struct qeth_ipa_cmd *cmd;
6866
6867 QETH_DBF_TEXT(trace,4,"chgmaccb");
6868
6869 cmd = (struct qeth_ipa_cmd *) data;
6870 if (!card->options.layer2 ||
6871 !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
6872 memcpy(card->dev->dev_addr,
6873 &cmd->data.setadapterparms.data.change_addr.addr,
6874 OSA_ADDR_LEN);
6875 card->info.mac_bits |= QETH_LAYER2_MAC_READ;
6876 }
6877 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
6878 return 0;
6879}
6880
6881static int
6882qeth_setadpparms_change_macaddr(struct qeth_card *card)
6883{
6884 int rc;
6885 struct qeth_cmd_buffer *iob;
6886 struct qeth_ipa_cmd *cmd;
6887
6888 QETH_DBF_TEXT(trace,4,"chgmac");
6889
6890 iob = qeth_get_adapter_cmd(card,IPA_SETADP_ALTER_MAC_ADDRESS,
6891 sizeof(struct qeth_ipacmd_setadpparms));
6892 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
6893 cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
6894 cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN;
6895 memcpy(&cmd->data.setadapterparms.data.change_addr.addr,
6896 card->dev->dev_addr, OSA_ADDR_LEN);
6897 rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_change_macaddr_cb,
6898 NULL);
6899 return rc;
6900}
6901
6902static int
6903qeth_send_setadp_mode(struct qeth_card *card, __u32 command, __u32 mode)
6904{
6905 int rc;
6906 struct qeth_cmd_buffer *iob;
6907 struct qeth_ipa_cmd *cmd;
6908
6909 QETH_DBF_TEXT(trace,4,"adpmode");
6910
6911 iob = qeth_get_adapter_cmd(card, command,
6912 sizeof(struct qeth_ipacmd_setadpparms));
6913 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
6914 cmd->data.setadapterparms.data.mode = mode;
6915 rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb,
6916 NULL);
6917 return rc;
6918}
6919
6920static int
6921qeth_setadapter_hstr(struct qeth_card *card)
6922{
6923 int rc;
6924
6925 QETH_DBF_TEXT(trace,4,"adphstr");
6926
6927 if (qeth_adp_supported(card,IPA_SETADP_SET_BROADCAST_MODE)) {
6928 rc = qeth_send_setadp_mode(card, IPA_SETADP_SET_BROADCAST_MODE,
6929 card->options.broadcast_mode);
6930 if (rc)
6931 PRINT_WARN("couldn't set broadcast mode on "
6932 "device %s: x%x\n",
6933 CARD_BUS_ID(card), rc);
6934 rc = qeth_send_setadp_mode(card, IPA_SETADP_ALTER_MAC_ADDRESS,
6935 card->options.macaddr_mode);
6936 if (rc)
6937 PRINT_WARN("couldn't set macaddr mode on "
6938 "device %s: x%x\n", CARD_BUS_ID(card), rc);
6939 return rc;
6940 }
6941 if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL)
6942 PRINT_WARN("set adapter parameters not available "
6943 "to set broadcast mode, using ALLRINGS "
6944 "on device %s:\n", CARD_BUS_ID(card));
6945 if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL)
6946 PRINT_WARN("set adapter parameters not available "
6947 "to set macaddr mode, using NONCANONICAL "
6948 "on device %s:\n", CARD_BUS_ID(card));
6949 return 0;
6950}
6951
6952static int
6953qeth_setadapter_parms(struct qeth_card *card)
6954{
6955 int rc;
6956
6957 QETH_DBF_TEXT(setup, 2, "setadprm");
6958
6959 if (!qeth_is_supported(card, IPA_SETADAPTERPARMS)){
6960 PRINT_WARN("set adapter parameters not supported "
6961 "on device %s.\n",
6962 CARD_BUS_ID(card));
6963 QETH_DBF_TEXT(setup, 2, " notsupp");
6964 return 0;
6965 }
6966 rc = qeth_query_setadapterparms(card);
6967 if (rc) {
6968 PRINT_WARN("couldn't set adapter parameters on device %s: "
6969 "x%x\n", CARD_BUS_ID(card), rc);
6970 return rc;
6971 }
6972 if (qeth_adp_supported(card,IPA_SETADP_ALTER_MAC_ADDRESS)) {
6973 rc = qeth_setadpparms_change_macaddr(card);
6974 if (rc)
6975 PRINT_WARN("couldn't get MAC address on "
6976 "device %s: x%x\n",
6977 CARD_BUS_ID(card), rc);
6978 }
6979
6980 if ((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
6981 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))
6982 rc = qeth_setadapter_hstr(card);
6983
6984 return rc;
6985}
6986
6987static int
6988qeth_layer2_initialize(struct qeth_card *card)
6989{
6990 int rc = 0;
6991
6992
6993 QETH_DBF_TEXT(setup, 2, "doL2init");
6994 QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));
6995
6996 rc = qeth_query_setadapterparms(card);
6997 if (rc) {
6998 PRINT_WARN("could not query adapter parameters on device %s: "
6999 "x%x\n", CARD_BUS_ID(card), rc);
7000 }
7001
7002 rc = qeth_setadpparms_change_macaddr(card);
7003 if (rc) {
7004 PRINT_WARN("couldn't get MAC address on "
7005 "device %s: x%x\n",
7006 CARD_BUS_ID(card), rc);
7007 QETH_DBF_TEXT_(setup, 2,"1err%d",rc);
7008 return rc;
7009 }
7010 QETH_DBF_HEX(setup,2, card->dev->dev_addr, OSA_ADDR_LEN);
7011
7012 rc = qeth_layer2_send_setmac(card, &card->dev->dev_addr[0]);
7013 if (rc)
7014 QETH_DBF_TEXT_(setup, 2,"2err%d",rc);
7015 return 0;
7016}
7017
7018
7019static int
7020qeth_send_startstoplan(struct qeth_card *card, enum qeth_ipa_cmds ipacmd,
7021 enum qeth_prot_versions prot)
7022{
7023 int rc;
7024 struct qeth_cmd_buffer *iob;
7025
7026 iob = qeth_get_ipacmd_buffer(card,ipacmd,prot);
7027 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
7028
7029 return rc;
7030}
7031
7032static int
7033qeth_send_startlan(struct qeth_card *card, enum qeth_prot_versions prot)
7034{
7035 int rc;
7036
7037 QETH_DBF_TEXT_(setup, 2, "strtlan%i", prot);
7038
7039 rc = qeth_send_startstoplan(card, IPA_CMD_STARTLAN, prot);
7040 return rc;
7041}
7042
7043static int
7044qeth_send_stoplan(struct qeth_card *card)
7045{
7046 int rc = 0;
7047
7048 /*
7049 * TODO: according to the IPA format document page 14,
7050 * TCP/IP (we!) never issue a STOPLAN
7051 * is this right ?!?
7052 */
7053 QETH_DBF_TEXT(trace, 2, "stoplan");
7054
7055 rc = qeth_send_startstoplan(card, IPA_CMD_STOPLAN, QETH_PROT_IPV4);
7056 return rc;
7057}
7058
7059static int
7060qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply,
7061 unsigned long data)
7062{
7063 struct qeth_ipa_cmd *cmd;
7064
7065 QETH_DBF_TEXT(setup, 2, "qipasscb");
7066
7067 cmd = (struct qeth_ipa_cmd *) data;
7068 if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
7069 card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
7070 card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
7071 /* Disable IPV6 support hard coded for Hipersockets */
7072 if(card->info.type == QETH_CARD_TYPE_IQD)
7073 card->options.ipa4.supported_funcs &= ~IPA_IPV6;
7074 } else {
7075#ifdef CONFIG_QETH_IPV6
7076 card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
7077 card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
7078#endif
7079 }
7080 QETH_DBF_TEXT(setup, 2, "suppenbl");
7081 QETH_DBF_TEXT_(setup, 2, "%x",cmd->hdr.ipa_supported);
7082 QETH_DBF_TEXT_(setup, 2, "%x",cmd->hdr.ipa_enabled);
7083 return 0;
7084}
7085
7086static int
7087qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot)
7088{
7089 int rc;
7090 struct qeth_cmd_buffer *iob;
7091
7092 QETH_DBF_TEXT_(setup, 2, "qipassi%i", prot);
7093 if (card->options.layer2) {
7094 QETH_DBF_TEXT(setup, 2, "noprmly2");
7095 return -EPERM;
7096 }
7097
7098 iob = qeth_get_ipacmd_buffer(card,IPA_CMD_QIPASSIST,prot);
7099 rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL);
7100 return rc;
7101}
7102
7103static struct qeth_cmd_buffer *
7104qeth_get_setassparms_cmd(struct qeth_card *card, enum qeth_ipa_funcs ipa_func,
7105 __u16 cmd_code, __u16 len,
7106 enum qeth_prot_versions prot)
7107{
7108 struct qeth_cmd_buffer *iob;
7109 struct qeth_ipa_cmd *cmd;
7110
7111 QETH_DBF_TEXT(trace,4,"getasscm");
7112 iob = qeth_get_ipacmd_buffer(card,IPA_CMD_SETASSPARMS,prot);
7113
7114 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
7115 cmd->data.setassparms.hdr.assist_no = ipa_func;
7116 cmd->data.setassparms.hdr.length = 8 + len;
7117 cmd->data.setassparms.hdr.command_code = cmd_code;
7118 cmd->data.setassparms.hdr.return_code = 0;
7119 cmd->data.setassparms.hdr.seq_no = 0;
7120
7121 return iob;
7122}
7123
7124static int
7125qeth_send_setassparms(struct qeth_card *card, struct qeth_cmd_buffer *iob,
7126 __u16 len, long data,
7127 int (*reply_cb)
7128 (struct qeth_card *,struct qeth_reply *,unsigned long),
7129 void *reply_param)
7130{
7131 int rc;
7132 struct qeth_ipa_cmd *cmd;
7133
7134 QETH_DBF_TEXT(trace,4,"sendassp");
7135
7136 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
7137 if (len <= sizeof(__u32))
7138 cmd->data.setassparms.data.flags_32bit = (__u32) data;
7139 else /* (len > sizeof(__u32)) */
7140 memcpy(&cmd->data.setassparms.data, (void *) data, len);
7141
7142 rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
7143 return rc;
7144}
7145
7146#ifdef CONFIG_QETH_IPV6
7147static int
7148qeth_send_simple_setassparms_ipv6(struct qeth_card *card,
7149 enum qeth_ipa_funcs ipa_func, __u16 cmd_code)
7150
7151{
7152 int rc;
7153 struct qeth_cmd_buffer *iob;
7154
7155 QETH_DBF_TEXT(trace,4,"simassp6");
7156 iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
7157 0, QETH_PROT_IPV6);
7158 rc = qeth_send_setassparms(card, iob, 0, 0,
7159 qeth_default_setassparms_cb, NULL);
7160 return rc;
7161}
7162#endif
7163
7164static int
7165qeth_send_simple_setassparms(struct qeth_card *card,
7166 enum qeth_ipa_funcs ipa_func,
7167 __u16 cmd_code, long data)
7168{
7169 int rc;
7170 int length = 0;
7171 struct qeth_cmd_buffer *iob;
7172
7173 QETH_DBF_TEXT(trace,4,"simassp4");
7174 if (data)
7175 length = sizeof(__u32);
7176 iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
7177 length, QETH_PROT_IPV4);
7178 rc = qeth_send_setassparms(card, iob, length, data,
7179 qeth_default_setassparms_cb, NULL);
7180 return rc;
7181}
7182
7183static int
7184qeth_start_ipa_arp_processing(struct qeth_card *card)
7185{
7186 int rc;
7187
7188 QETH_DBF_TEXT(trace,3,"ipaarp");
7189
7190 if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
7191 PRINT_WARN("ARP processing not supported "
7192 "on %s!\n", QETH_CARD_IFNAME(card));
7193 return 0;
7194 }
7195 rc = qeth_send_simple_setassparms(card,IPA_ARP_PROCESSING,
7196 IPA_CMD_ASS_START, 0);
7197 if (rc) {
7198 PRINT_WARN("Could not start ARP processing "
7199 "assist on %s: 0x%x\n",
7200 QETH_CARD_IFNAME(card), rc);
7201 }
7202 return rc;
7203}
7204
7205static int
7206qeth_start_ipa_ip_fragmentation(struct qeth_card *card)
7207{
7208 int rc;
7209
7210 QETH_DBF_TEXT(trace,3,"ipaipfrg");
7211
7212 if (!qeth_is_supported(card, IPA_IP_FRAGMENTATION)) {
7213 PRINT_INFO("Hardware IP fragmentation not supported on %s\n",
7214 QETH_CARD_IFNAME(card));
7215 return -EOPNOTSUPP;
7216 }
7217
7218 rc = qeth_send_simple_setassparms(card, IPA_IP_FRAGMENTATION,
7219 IPA_CMD_ASS_START, 0);
7220 if (rc) {
7221 PRINT_WARN("Could not start Hardware IP fragmentation "
7222 "assist on %s: 0x%x\n",
7223 QETH_CARD_IFNAME(card), rc);
7224 } else
7225 PRINT_INFO("Hardware IP fragmentation enabled \n");
7226 return rc;
7227}
7228
7229static int
7230qeth_start_ipa_source_mac(struct qeth_card *card)
7231{
7232 int rc;
7233
7234 QETH_DBF_TEXT(trace,3,"stsrcmac");
7235
7236 if (!card->options.fake_ll)
7237 return -EOPNOTSUPP;
7238
7239 if (!qeth_is_supported(card, IPA_SOURCE_MAC)) {
7240 PRINT_INFO("Inbound source address not "
7241 "supported on %s\n", QETH_CARD_IFNAME(card));
7242 return -EOPNOTSUPP;
7243 }
7244
7245 rc = qeth_send_simple_setassparms(card, IPA_SOURCE_MAC,
7246 IPA_CMD_ASS_START, 0);
7247 if (rc)
7248 PRINT_WARN("Could not start inbound source "
7249 "assist on %s: 0x%x\n",
7250 QETH_CARD_IFNAME(card), rc);
7251 return rc;
7252}
7253
7254static int
7255qeth_start_ipa_vlan(struct qeth_card *card)
7256{
7257 int rc = 0;
7258
7259 QETH_DBF_TEXT(trace,3,"strtvlan");
7260
7261#ifdef CONFIG_QETH_VLAN
7262 if (!qeth_is_supported(card, IPA_FULL_VLAN)) {
7263 PRINT_WARN("VLAN not supported on %s\n", QETH_CARD_IFNAME(card));
7264 return -EOPNOTSUPP;
7265 }
7266
7267 rc = qeth_send_simple_setassparms(card, IPA_VLAN_PRIO,
7268 IPA_CMD_ASS_START,0);
7269 if (rc) {
7270 PRINT_WARN("Could not start vlan "
7271 "assist on %s: 0x%x\n",
7272 QETH_CARD_IFNAME(card), rc);
7273 } else {
7274 PRINT_INFO("VLAN enabled \n");
7275 card->dev->features |=
7276 NETIF_F_HW_VLAN_FILTER |
7277 NETIF_F_HW_VLAN_TX |
7278 NETIF_F_HW_VLAN_RX;
7279 }
7280#endif /* QETH_VLAN */
7281 return rc;
7282}
7283
7284static int
7285qeth_start_ipa_multicast(struct qeth_card *card)
7286{
7287 int rc;
7288
7289 QETH_DBF_TEXT(trace,3,"stmcast");
7290
7291 if (!qeth_is_supported(card, IPA_MULTICASTING)) {
7292 PRINT_WARN("Multicast not supported on %s\n",
7293 QETH_CARD_IFNAME(card));
7294 return -EOPNOTSUPP;
7295 }
7296
7297 rc = qeth_send_simple_setassparms(card, IPA_MULTICASTING,
7298 IPA_CMD_ASS_START,0);
7299 if (rc) {
7300 PRINT_WARN("Could not start multicast "
7301 "assist on %s: rc=%i\n",
7302 QETH_CARD_IFNAME(card), rc);
7303 } else {
7304 PRINT_INFO("Multicast enabled\n");
7305 card->dev->flags |= IFF_MULTICAST;
7306 }
7307 return rc;
7308}
7309
7310#ifdef CONFIG_QETH_IPV6
7311static int
7312qeth_softsetup_ipv6(struct qeth_card *card)
7313{
7314 int rc;
7315
7316 QETH_DBF_TEXT(trace,3,"softipv6");
7317
7318 rc = qeth_send_startlan(card, QETH_PROT_IPV6);
7319 if (rc) {
7320 PRINT_ERR("IPv6 startlan failed on %s\n",
7321 QETH_CARD_IFNAME(card));
7322 return rc;
7323 }
7324 rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
7325 if (rc) {
7326 PRINT_ERR("IPv6 query ipassist failed on %s\n",
7327 QETH_CARD_IFNAME(card));
7328 return rc;
7329 }
7330 rc = qeth_send_simple_setassparms(card, IPA_IPV6,
7331 IPA_CMD_ASS_START, 3);
7332 if (rc) {
7333 PRINT_WARN("IPv6 start assist (version 4) failed "
7334 "on %s: 0x%x\n",
7335 QETH_CARD_IFNAME(card), rc);
7336 return rc;
7337 }
7338 rc = qeth_send_simple_setassparms_ipv6(card, IPA_IPV6,
7339 IPA_CMD_ASS_START);
7340 if (rc) {
7341 PRINT_WARN("IPV6 start assist (version 6) failed "
7342 "on %s: 0x%x\n",
7343 QETH_CARD_IFNAME(card), rc);
7344 return rc;
7345 }
7346 rc = qeth_send_simple_setassparms_ipv6(card, IPA_PASSTHRU,
7347 IPA_CMD_ASS_START);
7348 if (rc) {
7349 PRINT_WARN("Could not enable passthrough "
7350 "on %s: 0x%x\n",
7351 QETH_CARD_IFNAME(card), rc);
7352 return rc;
7353 }
7354 PRINT_INFO("IPV6 enabled \n");
7355 return 0;
7356}
7357
7358#endif
7359
7360static int
7361qeth_start_ipa_ipv6(struct qeth_card *card)
7362{
7363 int rc = 0;
7364#ifdef CONFIG_QETH_IPV6
7365 QETH_DBF_TEXT(trace,3,"strtipv6");
7366
7367 if (!qeth_is_supported(card, IPA_IPV6)) {
7368 PRINT_WARN("IPv6 not supported on %s\n",
7369 QETH_CARD_IFNAME(card));
7370 return 0;
7371 }
7372 rc = qeth_softsetup_ipv6(card);
7373#endif
7374 return rc ;
7375}
7376
7377static int
7378qeth_start_ipa_broadcast(struct qeth_card *card)
7379{
7380 int rc;
7381
7382 QETH_DBF_TEXT(trace,3,"stbrdcst");
7383 card->info.broadcast_capable = 0;
7384 if (!qeth_is_supported(card, IPA_FILTERING)) {
7385 PRINT_WARN("Broadcast not supported on %s\n",
7386 QETH_CARD_IFNAME(card));
7387 rc = -EOPNOTSUPP;
7388 goto out;
7389 }
7390 rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
7391 IPA_CMD_ASS_START, 0);
7392 if (rc) {
7393 PRINT_WARN("Could not enable broadcasting filtering "
7394 "on %s: 0x%x\n",
7395 QETH_CARD_IFNAME(card), rc);
7396 goto out;
7397 }
7398
7399 rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
7400 IPA_CMD_ASS_CONFIGURE, 1);
7401 if (rc) {
7402 PRINT_WARN("Could not set up broadcast filtering on %s: 0x%x\n",
7403 QETH_CARD_IFNAME(card), rc);
7404 goto out;
7405 }
7406 card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO;
7407 PRINT_INFO("Broadcast enabled \n");
7408 rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
7409 IPA_CMD_ASS_ENABLE, 1);
7410 if (rc) {
7411 PRINT_WARN("Could not set up broadcast echo filtering on "
7412 "%s: 0x%x\n", QETH_CARD_IFNAME(card), rc);
7413 goto out;
7414 }
7415 card->info.broadcast_capable = QETH_BROADCAST_WITHOUT_ECHO;
7416out:
7417 if (card->info.broadcast_capable)
7418 card->dev->flags |= IFF_BROADCAST;
7419 else
7420 card->dev->flags &= ~IFF_BROADCAST;
7421 return rc;
7422}
7423
7424static int
7425qeth_send_checksum_command(struct qeth_card *card)
7426{
7427 int rc;
7428
7429 rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
7430 IPA_CMD_ASS_START, 0);
7431 if (rc) {
7432 PRINT_WARN("Starting Inbound HW Checksumming failed on %s: "
7433 "0x%x,\ncontinuing using Inbound SW Checksumming\n",
7434 QETH_CARD_IFNAME(card), rc);
7435 return rc;
7436 }
7437 rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
7438 IPA_CMD_ASS_ENABLE,
7439 card->info.csum_mask);
7440 if (rc) {
7441 PRINT_WARN("Enabling Inbound HW Checksumming failed on %s: "
7442 "0x%x,\ncontinuing using Inbound SW Checksumming\n",
7443 QETH_CARD_IFNAME(card), rc);
7444 return rc;
7445 }
7446 return 0;
7447}
7448
7449static int
7450qeth_start_ipa_checksum(struct qeth_card *card)
7451{
7452 int rc = 0;
7453
7454 QETH_DBF_TEXT(trace,3,"strtcsum");
7455
7456 if (card->options.checksum_type == NO_CHECKSUMMING) {
7457 PRINT_WARN("Using no checksumming on %s.\n",
7458 QETH_CARD_IFNAME(card));
7459 return 0;
7460 }
7461 if (card->options.checksum_type == SW_CHECKSUMMING) {
7462 PRINT_WARN("Using SW checksumming on %s.\n",
7463 QETH_CARD_IFNAME(card));
7464 return 0;
7465 }
7466 if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
7467 PRINT_WARN("Inbound HW Checksumming not "
7468 "supported on %s,\ncontinuing "
7469 "using Inbound SW Checksumming\n",
7470 QETH_CARD_IFNAME(card));
7471 card->options.checksum_type = SW_CHECKSUMMING;
7472 return 0;
7473 }
7474 rc = qeth_send_checksum_command(card);
7475 if (!rc) {
7476 PRINT_INFO("HW Checksumming (inbound) enabled \n");
7477 }
7478 return rc;
7479}
7480
7481static int
7482qeth_start_ipa_tso(struct qeth_card *card)
7483{
7484 int rc;
7485
7486 QETH_DBF_TEXT(trace,3,"sttso");
7487
7488 if (!qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
7489 PRINT_WARN("Outbound TSO not supported on %s\n",
7490 QETH_CARD_IFNAME(card));
7491 rc = -EOPNOTSUPP;
7492 } else {
7493 rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
7494 IPA_CMD_ASS_START,0);
7495 if (rc)
7496 PRINT_WARN("Could not start outbound TSO "
7497 "assist on %s: rc=%i\n",
7498 QETH_CARD_IFNAME(card), rc);
7499 else
7500 PRINT_INFO("Outbound TSO enabled\n");
7501 }
7502 if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)){
7503 card->options.large_send = QETH_LARGE_SEND_NO;
7504 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
7505 NETIF_F_HW_CSUM);
7506 }
7507 return rc;
7508}
7509
7510static int
7511qeth_start_ipassists(struct qeth_card *card)
7512{
7513 QETH_DBF_TEXT(trace,3,"strtipas");
7514 qeth_start_ipa_arp_processing(card); /* go on*/
7515 qeth_start_ipa_ip_fragmentation(card); /* go on*/
7516 qeth_start_ipa_source_mac(card); /* go on*/
7517 qeth_start_ipa_vlan(card); /* go on*/
7518 qeth_start_ipa_multicast(card); /* go on*/
7519 qeth_start_ipa_ipv6(card); /* go on*/
7520 qeth_start_ipa_broadcast(card); /* go on*/
7521 qeth_start_ipa_checksum(card); /* go on*/
7522 qeth_start_ipa_tso(card); /* go on*/
7523 return 0;
7524}
7525
7526static int
7527qeth_send_setrouting(struct qeth_card *card, enum qeth_routing_types type,
7528 enum qeth_prot_versions prot)
7529{
7530 int rc;
7531 struct qeth_ipa_cmd *cmd;
7532 struct qeth_cmd_buffer *iob;
7533
7534 QETH_DBF_TEXT(trace,4,"setroutg");
7535 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot);
7536 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
7537 cmd->data.setrtg.type = (type);
7538 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
7539
7540 return rc;
7541
7542}
7543
7544static void
7545qeth_correct_routing_type(struct qeth_card *card, enum qeth_routing_types *type,
7546 enum qeth_prot_versions prot)
7547{
7548 if (card->info.type == QETH_CARD_TYPE_IQD) {
7549 switch (*type) {
7550 case NO_ROUTER:
7551 case PRIMARY_CONNECTOR:
7552 case SECONDARY_CONNECTOR:
7553 case MULTICAST_ROUTER:
7554 return;
7555 default:
7556 goto out_inval;
7557 }
7558 } else {
7559 switch (*type) {
7560 case NO_ROUTER:
7561 case PRIMARY_ROUTER:
7562 case SECONDARY_ROUTER:
7563 return;
7564 case MULTICAST_ROUTER:
7565 if (qeth_is_ipafunc_supported(card, prot,
7566 IPA_OSA_MC_ROUTER))
7567 return;
7568 default:
7569 goto out_inval;
7570 }
7571 }
7572out_inval:
7573 PRINT_WARN("Routing type '%s' not supported for interface %s.\n"
7574 "Router status set to 'no router'.\n",
7575 ((*type == PRIMARY_ROUTER)? "primary router" :
7576 (*type == SECONDARY_ROUTER)? "secondary router" :
7577 (*type == PRIMARY_CONNECTOR)? "primary connector" :
7578 (*type == SECONDARY_CONNECTOR)? "secondary connector" :
7579 (*type == MULTICAST_ROUTER)? "multicast router" :
7580 "unknown"),
7581 card->dev->name);
7582 *type = NO_ROUTER;
7583}
7584
7585int
7586qeth_setrouting_v4(struct qeth_card *card)
7587{
7588 int rc;
7589
7590 QETH_DBF_TEXT(trace,3,"setrtg4");
7591
7592 qeth_correct_routing_type(card, &card->options.route4.type,
7593 QETH_PROT_IPV4);
7594
7595 rc = qeth_send_setrouting(card, card->options.route4.type,
7596 QETH_PROT_IPV4);
7597 if (rc) {
7598 card->options.route4.type = NO_ROUTER;
7599 PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
7600 "Type set to 'no router'.\n",
7601 rc, QETH_CARD_IFNAME(card));
7602 }
7603 return rc;
7604}
7605
7606int
7607qeth_setrouting_v6(struct qeth_card *card)
7608{
7609 int rc = 0;
7610
7611 QETH_DBF_TEXT(trace,3,"setrtg6");
7612#ifdef CONFIG_QETH_IPV6
7613
7614 if (!qeth_is_supported(card, IPA_IPV6))
7615 return 0;
7616 qeth_correct_routing_type(card, &card->options.route6.type,
7617 QETH_PROT_IPV6);
7618
7619 rc = qeth_send_setrouting(card, card->options.route6.type,
7620 QETH_PROT_IPV6);
7621 if (rc) {
7622 card->options.route6.type = NO_ROUTER;
7623 PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
7624 "Type set to 'no router'.\n",
7625 rc, QETH_CARD_IFNAME(card));
7626 }
7627#endif
7628 return rc;
7629}
7630
7631int
7632qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
7633{
7634 int rc = 0;
7635
7636 if (card->dev == NULL) {
7637 card->options.large_send = type;
7638 return 0;
7639 }
7640 if (card->state == CARD_STATE_UP)
7641 netif_tx_disable(card->dev);
7642 card->options.large_send = type;
7643 switch (card->options.large_send) {
7644 case QETH_LARGE_SEND_EDDP:
7645 card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
7646 NETIF_F_HW_CSUM;
7647 break;
7648 case QETH_LARGE_SEND_TSO:
7649 if (qeth_is_supported(card, IPA_OUTBOUND_TSO)){
7650 card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
7651 NETIF_F_HW_CSUM;
7652 } else {
7653 PRINT_WARN("TSO not supported on %s. "
7654 "large_send set to 'no'.\n",
7655 card->dev->name);
7656 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
7657 NETIF_F_HW_CSUM);
7658 card->options.large_send = QETH_LARGE_SEND_NO;
7659 rc = -EOPNOTSUPP;
7660 }
7661 break;
7662 default: /* includes QETH_LARGE_SEND_NO */
7663 card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
7664 NETIF_F_HW_CSUM);
7665 break;
7666 }
7667 if (card->state == CARD_STATE_UP)
7668 netif_wake_queue(card->dev);
7669 return rc;
7670}
7671
7672/*
7673 * softsetup card: init IPA stuff
7674 */
7675static int
7676qeth_softsetup_card(struct qeth_card *card)
7677{
7678 int rc;
7679
7680 QETH_DBF_TEXT(setup, 2, "softsetp");
7681
7682 if ((rc = qeth_send_startlan(card, QETH_PROT_IPV4))){
7683 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
7684 if (rc == 0xe080){
7685 PRINT_WARN("LAN on card %s if offline! "
7686 "Waiting for STARTLAN from card.\n",
7687 CARD_BUS_ID(card));
7688 card->lan_online = 0;
7689 }
7690 return rc;
7691 } else
7692 card->lan_online = 1;
7693 if (card->info.type==QETH_CARD_TYPE_OSN)
7694 goto out;
7695 qeth_set_large_send(card, card->options.large_send);
7696 if (card->options.layer2) {
7697 card->dev->features |=
7698 NETIF_F_HW_VLAN_FILTER |
7699 NETIF_F_HW_VLAN_TX |
7700 NETIF_F_HW_VLAN_RX;
7701 card->dev->flags|=IFF_MULTICAST|IFF_BROADCAST;
7702 card->info.broadcast_capable=1;
7703 if ((rc = qeth_layer2_initialize(card))) {
7704 QETH_DBF_TEXT_(setup, 2, "L2err%d", rc);
7705 return rc;
7706 }
7707#ifdef CONFIG_QETH_VLAN
7708 qeth_layer2_process_vlans(card, 0);
7709#endif
7710 goto out;
7711 }
7712 if ((rc = qeth_setadapter_parms(card)))
7713 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
7714 if ((rc = qeth_start_ipassists(card)))
7715 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
7716 if ((rc = qeth_setrouting_v4(card)))
7717 QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
7718 if ((rc = qeth_setrouting_v6(card)))
7719 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
7720out:
7721 netif_tx_disable(card->dev);
7722 return 0;
7723}
7724
7725#ifdef CONFIG_QETH_IPV6
7726static int
7727qeth_get_unique_id_cb(struct qeth_card *card, struct qeth_reply *reply,
7728 unsigned long data)
7729{
7730 struct qeth_ipa_cmd *cmd;
7731
7732 cmd = (struct qeth_ipa_cmd *) data;
7733 if (cmd->hdr.return_code == 0)
7734 card->info.unique_id = *((__u16 *)
7735 &cmd->data.create_destroy_addr.unique_id[6]);
7736 else {
7737 card->info.unique_id = UNIQUE_ID_IF_CREATE_ADDR_FAILED |
7738 UNIQUE_ID_NOT_BY_CARD;
7739 PRINT_WARN("couldn't get a unique id from the card on device "
7740 "%s (result=x%x), using default id. ipv6 "
7741 "autoconfig on other lpars may lead to duplicate "
7742 "ip addresses. please use manually "
7743 "configured ones.\n",
7744 CARD_BUS_ID(card), cmd->hdr.return_code);
7745 }
7746 return 0;
7747}
7748#endif
7749
7750static int
7751qeth_put_unique_id(struct qeth_card *card)
7752{
7753
7754 int rc = 0;
7755#ifdef CONFIG_QETH_IPV6
7756 struct qeth_cmd_buffer *iob;
7757 struct qeth_ipa_cmd *cmd;
7758
7759 QETH_DBF_TEXT(trace,2,"puniqeid");
7760
7761 if ((card->info.unique_id & UNIQUE_ID_NOT_BY_CARD) ==
7762 UNIQUE_ID_NOT_BY_CARD)
7763 return -1;
7764 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_DESTROY_ADDR,
7765 QETH_PROT_IPV6);
7766 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
7767 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
7768 card->info.unique_id;
7769 memcpy(&cmd->data.create_destroy_addr.unique_id[0],
7770 card->dev->dev_addr, OSA_ADDR_LEN);
7771 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
7772#else
7773 card->info.unique_id = UNIQUE_ID_IF_CREATE_ADDR_FAILED |
7774 UNIQUE_ID_NOT_BY_CARD;
7775#endif
7776 return rc;
7777}
7778
7779/**
7780 * Clear IP List
7781 */
7782static void
7783qeth_clear_ip_list(struct qeth_card *card, int clean, int recover)
7784{
7785 struct qeth_ipaddr *addr, *tmp;
7786 unsigned long flags;
7787
7788 QETH_DBF_TEXT(trace,4,"clearip");
7789 spin_lock_irqsave(&card->ip_lock, flags);
7790 /* clear todo list */
7791 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry){
7792 list_del(&addr->entry);
7793 kfree(addr);
7794 }
7795
7796 while (!list_empty(&card->ip_list)) {
7797 addr = list_entry(card->ip_list.next,
7798 struct qeth_ipaddr, entry);
7799 list_del_init(&addr->entry);
7800 if (clean) {
7801 spin_unlock_irqrestore(&card->ip_lock, flags);
7802 qeth_deregister_addr_entry(card, addr);
7803 spin_lock_irqsave(&card->ip_lock, flags);
7804 }
7805 if (!recover || addr->is_multicast) {
7806 kfree(addr);
7807 continue;
7808 }
7809 list_add_tail(&addr->entry, card->ip_tbd_list);
7810 }
7811 spin_unlock_irqrestore(&card->ip_lock, flags);
7812}
7813
7814static void
7815qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
7816 int clear_start_mask)
7817{
7818 unsigned long flags;
7819
7820 spin_lock_irqsave(&card->thread_mask_lock, flags);
7821 card->thread_allowed_mask = threads;
7822 if (clear_start_mask)
7823 card->thread_start_mask &= threads;
7824 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
7825 wake_up(&card->wait_q);
7826}
7827
7828static int
7829qeth_threads_running(struct qeth_card *card, unsigned long threads)
7830{
7831 unsigned long flags;
7832 int rc = 0;
7833
7834 spin_lock_irqsave(&card->thread_mask_lock, flags);
7835 rc = (card->thread_running_mask & threads);
7836 spin_unlock_irqrestore(&card->thread_mask_lock, flags);
7837 return rc;
7838}
7839
7840static int
7841qeth_wait_for_threads(struct qeth_card *card, unsigned long threads)
7842{
7843 return wait_event_interruptible(card->wait_q,
7844 qeth_threads_running(card, threads) == 0);
7845}
7846
7847static int
7848qeth_stop_card(struct qeth_card *card, int recovery_mode)
7849{
7850 int rc = 0;
7851
7852 QETH_DBF_TEXT(setup ,2,"stopcard");
7853 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
7854
7855 qeth_set_allowed_threads(card, 0, 1);
7856 if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD))
7857 return -ERESTARTSYS;
7858 if (card->read.state == CH_STATE_UP &&
7859 card->write.state == CH_STATE_UP &&
7860 (card->state == CARD_STATE_UP)) {
7861 if (recovery_mode &&
7862 card->info.type != QETH_CARD_TYPE_OSN) {
7863 qeth_stop(card->dev);
7864 } else {
7865 rtnl_lock();
7866 dev_close(card->dev);
7867 rtnl_unlock();
7868 }
7869 if (!card->use_hard_stop) {
7870 __u8 *mac = &card->dev->dev_addr[0];
7871 rc = qeth_layer2_send_delmac(card, mac);
7872 QETH_DBF_TEXT_(setup, 2, "Lerr%d", rc);
7873 if ((rc = qeth_send_stoplan(card)))
7874 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
7875 }
7876 card->state = CARD_STATE_SOFTSETUP;
7877 }
7878 if (card->state == CARD_STATE_SOFTSETUP) {
7879#ifdef CONFIG_QETH_VLAN
7880 if (card->options.layer2)
7881 qeth_layer2_process_vlans(card, 1);
7882#endif
7883 qeth_clear_ip_list(card, !card->use_hard_stop, 1);
7884 qeth_clear_ipacmd_list(card);
7885 card->state = CARD_STATE_HARDSETUP;
7886 }
7887 if (card->state == CARD_STATE_HARDSETUP) {
7888 if ((!card->use_hard_stop) &&
7889 (!card->options.layer2))
7890 if ((rc = qeth_put_unique_id(card)))
7891 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
7892 qeth_qdio_clear_card(card, 0);
7893 qeth_clear_qdio_buffers(card);
7894 qeth_clear_working_pool_list(card);
7895 card->state = CARD_STATE_DOWN;
7896 }
7897 if (card->state == CARD_STATE_DOWN) {
7898 qeth_clear_cmd_buffers(&card->read);
7899 qeth_clear_cmd_buffers(&card->write);
7900 }
7901 card->use_hard_stop = 0;
7902 return rc;
7903}
7904
7905
7906static int
7907qeth_get_unique_id(struct qeth_card *card)
7908{
7909 int rc = 0;
7910#ifdef CONFIG_QETH_IPV6
7911 struct qeth_cmd_buffer *iob;
7912 struct qeth_ipa_cmd *cmd;
7913
7914 QETH_DBF_TEXT(setup, 2, "guniqeid");
7915
7916 if (!qeth_is_supported(card,IPA_IPV6)) {
7917 card->info.unique_id = UNIQUE_ID_IF_CREATE_ADDR_FAILED |
7918 UNIQUE_ID_NOT_BY_CARD;
7919 return 0;
7920 }
7921
7922 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR,
7923 QETH_PROT_IPV6);
7924 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
7925 *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
7926 card->info.unique_id;
7927
7928 rc = qeth_send_ipa_cmd(card, iob, qeth_get_unique_id_cb, NULL);
7929#else
7930 card->info.unique_id = UNIQUE_ID_IF_CREATE_ADDR_FAILED |
7931 UNIQUE_ID_NOT_BY_CARD;
7932#endif
7933 return rc;
7934}
7935static void
7936qeth_print_status_with_portname(struct qeth_card *card)
7937{
7938 char dbf_text[15];
7939 int i;
7940
7941 sprintf(dbf_text, "%s", card->info.portname + 1);
7942 for (i = 0; i < 8; i++)
7943 dbf_text[i] =
7944 (char) _ebcasc[(__u8) dbf_text[i]];
7945 dbf_text[8] = 0;
7946 printk("qeth: Device %s/%s/%s is a%s card%s%s%s\n"
7947 "with link type %s (portname: %s)\n",
7948 CARD_RDEV_ID(card),
7949 CARD_WDEV_ID(card),
7950 CARD_DDEV_ID(card),
7951 qeth_get_cardname(card),
7952 (card->info.mcl_level[0]) ? " (level: " : "",
7953 (card->info.mcl_level[0]) ? card->info.mcl_level : "",
7954 (card->info.mcl_level[0]) ? ")" : "",
7955 qeth_get_cardname_short(card),
7956 dbf_text);
7957
7958}
7959
7960static void
7961qeth_print_status_no_portname(struct qeth_card *card)
7962{
7963 if (card->info.portname[0])
7964 printk("qeth: Device %s/%s/%s is a%s "
7965 "card%s%s%s\nwith link type %s "
7966 "(no portname needed by interface).\n",
7967 CARD_RDEV_ID(card),
7968 CARD_WDEV_ID(card),
7969 CARD_DDEV_ID(card),
7970 qeth_get_cardname(card),
7971 (card->info.mcl_level[0]) ? " (level: " : "",
7972 (card->info.mcl_level[0]) ? card->info.mcl_level : "",
7973 (card->info.mcl_level[0]) ? ")" : "",
7974 qeth_get_cardname_short(card));
7975 else
7976 printk("qeth: Device %s/%s/%s is a%s "
7977 "card%s%s%s\nwith link type %s.\n",
7978 CARD_RDEV_ID(card),
7979 CARD_WDEV_ID(card),
7980 CARD_DDEV_ID(card),
7981 qeth_get_cardname(card),
7982 (card->info.mcl_level[0]) ? " (level: " : "",
7983 (card->info.mcl_level[0]) ? card->info.mcl_level : "",
7984 (card->info.mcl_level[0]) ? ")" : "",
7985 qeth_get_cardname_short(card));
7986}
7987
7988static void
7989qeth_print_status_message(struct qeth_card *card)
7990{
7991 switch (card->info.type) {
7992 case QETH_CARD_TYPE_OSAE:
7993 /* VM will use a non-zero first character
7994 * to indicate a HiperSockets like reporting
7995 * of the level OSA sets the first character to zero
7996 * */
7997 if (!card->info.mcl_level[0]) {
7998 sprintf(card->info.mcl_level,"%02x%02x",
7999 card->info.mcl_level[2],
8000 card->info.mcl_level[3]);
8001
8002 card->info.mcl_level[QETH_MCL_LENGTH] = 0;
8003 break;
8004 }
8005 /* fallthrough */
8006 case QETH_CARD_TYPE_IQD:
8007 if (card->info.guestlan) {
8008 card->info.mcl_level[0] = (char) _ebcasc[(__u8)
8009 card->info.mcl_level[0]];
8010 card->info.mcl_level[1] = (char) _ebcasc[(__u8)
8011 card->info.mcl_level[1]];
8012 card->info.mcl_level[2] = (char) _ebcasc[(__u8)
8013 card->info.mcl_level[2]];
8014 card->info.mcl_level[3] = (char) _ebcasc[(__u8)
8015 card->info.mcl_level[3]];
8016 card->info.mcl_level[QETH_MCL_LENGTH] = 0;
8017 }
8018 break;
8019 default:
8020 memset(&card->info.mcl_level[0], 0, QETH_MCL_LENGTH + 1);
8021 }
8022 if (card->info.portname_required)
8023 qeth_print_status_with_portname(card);
8024 else
8025 qeth_print_status_no_portname(card);
8026}
8027
8028static int
8029qeth_register_netdev(struct qeth_card *card)
8030{
8031 QETH_DBF_TEXT(setup, 3, "regnetd");
8032 if (card->dev->reg_state != NETREG_UNINITIALIZED)
8033 return 0;
8034 /* sysfs magic */
8035 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
8036 return register_netdev(card->dev);
8037}
8038
8039static void
8040qeth_start_again(struct qeth_card *card, int recovery_mode)
8041{
8042 QETH_DBF_TEXT(setup ,2, "startag");
8043
8044 if (recovery_mode &&
8045 card->info.type != QETH_CARD_TYPE_OSN) {
8046 qeth_open(card->dev);
8047 } else {
8048 rtnl_lock();
8049 dev_open(card->dev);
8050 rtnl_unlock();
8051 }
8052 /* this also sets saved unicast addresses */
8053 qeth_set_multicast_list(card->dev);
8054}
8055
8056
8057/* Layer 2 specific stuff */
8058#define IGNORE_PARAM_EQ(option,value,reset_value,msg) \
8059 if (card->options.option == value) { \
8060 PRINT_ERR("%s not supported with layer 2 " \
8061 "functionality, ignoring option on read" \
8062 "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
8063 card->options.option = reset_value; \
8064 }
8065#define IGNORE_PARAM_NEQ(option,value,reset_value,msg) \
8066 if (card->options.option != value) { \
8067 PRINT_ERR("%s not supported with layer 2 " \
8068 "functionality, ignoring option on read" \
8069 "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
8070 card->options.option = reset_value; \
8071 }
8072
8073
8074static void qeth_make_parameters_consistent(struct qeth_card *card)
8075{
8076
8077 if (card->options.layer2 == 0)
8078 return;
8079 if (card->info.type == QETH_CARD_TYPE_OSN)
8080 return;
8081 if (card->info.type == QETH_CARD_TYPE_IQD) {
8082 PRINT_ERR("Device %s does not support layer 2 functionality." \
8083 " Ignoring layer2 option.\n",CARD_BUS_ID(card));
8084 card->options.layer2 = 0;
8085 return;
8086 }
8087 IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
8088 "Routing options are");
8089#ifdef CONFIG_QETH_IPV6
8090 IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
8091 "Routing options are");
8092#endif
8093 IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
8094 QETH_CHECKSUM_DEFAULT,
8095 "Checksumming options are");
8096 IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
8097 QETH_TR_BROADCAST_ALLRINGS,
8098 "Broadcast mode options are");
8099 IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
8100 QETH_TR_MACADDR_NONCANONICAL,
8101 "Canonical MAC addr options are");
8102 IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
8103 "Broadcast faking options are");
8104 IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
8105 DEFAULT_ADD_HHLEN,"Option add_hhlen is");
8106 IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
8107}
8108
8109
8110static int
8111__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
8112{
8113 struct qeth_card *card = gdev->dev.driver_data;
8114 int rc = 0;
8115 enum qeth_card_states recover_flag;
8116
8117 BUG_ON(!card);
8118 QETH_DBF_TEXT(setup ,2, "setonlin");
8119 QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
8120
8121 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
8122 if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)){
8123 PRINT_WARN("set_online of card %s interrupted by user!\n",
8124 CARD_BUS_ID(card));
8125 return -ERESTARTSYS;
8126 }
8127
8128 recover_flag = card->state;
8129 if ((rc = ccw_device_set_online(CARD_RDEV(card))) ||
8130 (rc = ccw_device_set_online(CARD_WDEV(card))) ||
8131 (rc = ccw_device_set_online(CARD_DDEV(card)))){
8132 QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
8133 return -EIO;
8134 }
8135
8136 qeth_make_parameters_consistent(card);
8137
8138 if ((rc = qeth_hardsetup_card(card))){
8139 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
8140 goto out_remove;
8141 }
8142 card->state = CARD_STATE_HARDSETUP;
8143
8144 if (!(rc = qeth_query_ipassists(card,QETH_PROT_IPV4)))
8145 rc = qeth_get_unique_id(card);
8146
8147 if (rc && card->options.layer2 == 0) {
8148 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
8149 goto out_remove;
8150 }
8151 qeth_print_status_message(card);
8152 if ((rc = qeth_register_netdev(card))){
8153 QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
8154 goto out_remove;
8155 }
8156 if ((rc = qeth_softsetup_card(card))){
8157 QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
8158 goto out_remove;
8159 }
8160
8161 if ((rc = qeth_init_qdio_queues(card))){
8162 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
8163 goto out_remove;
8164 }
8165 card->state = CARD_STATE_SOFTSETUP;
8166 netif_carrier_on(card->dev);
8167
8168 qeth_set_allowed_threads(card, 0xffffffff, 0);
8169 if (recover_flag == CARD_STATE_RECOVER)
8170 qeth_start_again(card, recovery_mode);
8171 qeth_notify_processes();
8172 return 0;
8173out_remove:
8174 card->use_hard_stop = 1;
8175 qeth_stop_card(card, 0);
8176 ccw_device_set_offline(CARD_DDEV(card));
8177 ccw_device_set_offline(CARD_WDEV(card));
8178 ccw_device_set_offline(CARD_RDEV(card));
8179 if (recover_flag == CARD_STATE_RECOVER)
8180 card->state = CARD_STATE_RECOVER;
8181 else
8182 card->state = CARD_STATE_DOWN;
8183 return -ENODEV;
8184}
8185
8186static int
8187qeth_set_online(struct ccwgroup_device *gdev)
8188{
8189 return __qeth_set_online(gdev, 0);
8190}
8191
8192static struct ccw_device_id qeth_ids[] = {
8193 {CCW_DEVICE(0x1731, 0x01), .driver_info = QETH_CARD_TYPE_OSAE},
8194 {CCW_DEVICE(0x1731, 0x05), .driver_info = QETH_CARD_TYPE_IQD},
8195 {CCW_DEVICE(0x1731, 0x06), .driver_info = QETH_CARD_TYPE_OSN},
8196 {},
8197};
8198MODULE_DEVICE_TABLE(ccw, qeth_ids);
8199
8200struct device *qeth_root_dev = NULL;
8201
8202struct ccwgroup_driver qeth_ccwgroup_driver = {
8203 .owner = THIS_MODULE,
8204 .name = "qeth",
8205 .driver_id = 0xD8C5E3C8,
8206 .probe = qeth_probe_device,
8207 .remove = qeth_remove_device,
8208 .set_online = qeth_set_online,
8209 .set_offline = qeth_set_offline,
8210};
8211
8212struct ccw_driver qeth_ccw_driver = {
8213 .name = "qeth",
8214 .ids = qeth_ids,
8215 .probe = ccwgroup_probe_ccwdev,
8216 .remove = ccwgroup_remove_ccwdev,
8217};
8218
8219
8220static void
8221qeth_unregister_dbf_views(void)
8222{
8223 if (qeth_dbf_setup)
8224 debug_unregister(qeth_dbf_setup);
8225 if (qeth_dbf_qerr)
8226 debug_unregister(qeth_dbf_qerr);
8227 if (qeth_dbf_sense)
8228 debug_unregister(qeth_dbf_sense);
8229 if (qeth_dbf_misc)
8230 debug_unregister(qeth_dbf_misc);
8231 if (qeth_dbf_data)
8232 debug_unregister(qeth_dbf_data);
8233 if (qeth_dbf_control)
8234 debug_unregister(qeth_dbf_control);
8235 if (qeth_dbf_trace)
8236 debug_unregister(qeth_dbf_trace);
8237}
8238static int
8239qeth_register_dbf_views(void)
8240{
8241 qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME,
8242 QETH_DBF_SETUP_PAGES,
8243 QETH_DBF_SETUP_NR_AREAS,
8244 QETH_DBF_SETUP_LEN);
8245 qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME,
8246 QETH_DBF_MISC_PAGES,
8247 QETH_DBF_MISC_NR_AREAS,
8248 QETH_DBF_MISC_LEN);
8249 qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME,
8250 QETH_DBF_DATA_PAGES,
8251 QETH_DBF_DATA_NR_AREAS,
8252 QETH_DBF_DATA_LEN);
8253 qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME,
8254 QETH_DBF_CONTROL_PAGES,
8255 QETH_DBF_CONTROL_NR_AREAS,
8256 QETH_DBF_CONTROL_LEN);
8257 qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME,
8258 QETH_DBF_SENSE_PAGES,
8259 QETH_DBF_SENSE_NR_AREAS,
8260 QETH_DBF_SENSE_LEN);
8261 qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME,
8262 QETH_DBF_QERR_PAGES,
8263 QETH_DBF_QERR_NR_AREAS,
8264 QETH_DBF_QERR_LEN);
8265 qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME,
8266 QETH_DBF_TRACE_PAGES,
8267 QETH_DBF_TRACE_NR_AREAS,
8268 QETH_DBF_TRACE_LEN);
8269
8270 if ((qeth_dbf_setup == NULL) || (qeth_dbf_misc == NULL) ||
8271 (qeth_dbf_data == NULL) || (qeth_dbf_control == NULL) ||
8272 (qeth_dbf_sense == NULL) || (qeth_dbf_qerr == NULL) ||
8273 (qeth_dbf_trace == NULL)) {
8274 qeth_unregister_dbf_views();
8275 return -ENOMEM;
8276 }
8277 debug_register_view(qeth_dbf_setup, &debug_hex_ascii_view);
8278 debug_set_level(qeth_dbf_setup, QETH_DBF_SETUP_LEVEL);
8279
8280 debug_register_view(qeth_dbf_misc, &debug_hex_ascii_view);
8281 debug_set_level(qeth_dbf_misc, QETH_DBF_MISC_LEVEL);
8282
8283 debug_register_view(qeth_dbf_data, &debug_hex_ascii_view);
8284 debug_set_level(qeth_dbf_data, QETH_DBF_DATA_LEVEL);
8285
8286 debug_register_view(qeth_dbf_control, &debug_hex_ascii_view);
8287 debug_set_level(qeth_dbf_control, QETH_DBF_CONTROL_LEVEL);
8288
8289 debug_register_view(qeth_dbf_sense, &debug_hex_ascii_view);
8290 debug_set_level(qeth_dbf_sense, QETH_DBF_SENSE_LEVEL);
8291
8292 debug_register_view(qeth_dbf_qerr, &debug_hex_ascii_view);
8293 debug_set_level(qeth_dbf_qerr, QETH_DBF_QERR_LEVEL);
8294
8295 debug_register_view(qeth_dbf_trace, &debug_hex_ascii_view);
8296 debug_set_level(qeth_dbf_trace, QETH_DBF_TRACE_LEVEL);
8297
8298 return 0;
8299}
8300
8301#ifdef CONFIG_QETH_IPV6
8302extern struct neigh_table arp_tbl;
8303static struct neigh_ops *arp_direct_ops;
8304static int (*qeth_old_arp_constructor) (struct neighbour *);
8305
8306static struct neigh_ops arp_direct_ops_template = {
8307 .family = AF_INET,
8308 .solicit = NULL,
8309 .error_report = NULL,
8310 .output = dev_queue_xmit,
8311 .connected_output = dev_queue_xmit,
8312 .hh_output = dev_queue_xmit,
8313 .queue_xmit = dev_queue_xmit
8314};
8315
8316static int
8317qeth_arp_constructor(struct neighbour *neigh)
8318{
8319 struct net_device *dev = neigh->dev;
8320 struct in_device *in_dev;
8321 struct neigh_parms *parms;
8322 struct qeth_card *card;
8323
8324 card = qeth_get_card_from_dev(dev);
8325 if (card == NULL)
8326 goto out;
8327 if((card->options.layer2) ||
8328 (card->dev->header_ops == &qeth_fake_ops))
8329 goto out;
8330
8331 rcu_read_lock();
8332 in_dev = __in_dev_get_rcu(dev);
8333 if (in_dev == NULL) {
8334 rcu_read_unlock();
8335 return -EINVAL;
8336 }
8337
8338 parms = in_dev->arp_parms;
8339 __neigh_parms_put(neigh->parms);
8340 neigh->parms = neigh_parms_clone(parms);
8341 rcu_read_unlock();
8342
8343 neigh->type = inet_addr_type(&init_net, *(__be32 *) neigh->primary_key);
8344 neigh->nud_state = NUD_NOARP;
8345 neigh->ops = arp_direct_ops;
8346 neigh->output = neigh->ops->queue_xmit;
8347 return 0;
8348out:
8349 return qeth_old_arp_constructor(neigh);
8350}
8351#endif /*CONFIG_QETH_IPV6*/
8352
8353/*
8354 * IP address takeover related functions
8355 */
8356static void
8357qeth_clear_ipato_list(struct qeth_card *card)
8358{
8359 struct qeth_ipato_entry *ipatoe, *tmp;
8360 unsigned long flags;
8361
8362 spin_lock_irqsave(&card->ip_lock, flags);
8363 list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry) {
8364 list_del(&ipatoe->entry);
8365 kfree(ipatoe);
8366 }
8367 spin_unlock_irqrestore(&card->ip_lock, flags);
8368}
8369
8370int
8371qeth_add_ipato_entry(struct qeth_card *card, struct qeth_ipato_entry *new)
8372{
8373 struct qeth_ipato_entry *ipatoe;
8374 unsigned long flags;
8375 int rc = 0;
8376
8377 QETH_DBF_TEXT(trace, 2, "addipato");
8378 spin_lock_irqsave(&card->ip_lock, flags);
8379 list_for_each_entry(ipatoe, &card->ipato.entries, entry){
8380 if (ipatoe->proto != new->proto)
8381 continue;
8382 if (!memcmp(ipatoe->addr, new->addr,
8383 (ipatoe->proto == QETH_PROT_IPV4)? 4:16) &&
8384 (ipatoe->mask_bits == new->mask_bits)){
8385 PRINT_WARN("ipato entry already exists!\n");
8386 rc = -EEXIST;
8387 break;
8388 }
8389 }
8390 if (!rc) {
8391 list_add_tail(&new->entry, &card->ipato.entries);
8392 }
8393 spin_unlock_irqrestore(&card->ip_lock, flags);
8394 return rc;
8395}
8396
8397void
8398qeth_del_ipato_entry(struct qeth_card *card, enum qeth_prot_versions proto,
8399 u8 *addr, int mask_bits)
8400{
8401 struct qeth_ipato_entry *ipatoe, *tmp;
8402 unsigned long flags;
8403
8404 QETH_DBF_TEXT(trace, 2, "delipato");
8405 spin_lock_irqsave(&card->ip_lock, flags);
8406 list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry){
8407 if (ipatoe->proto != proto)
8408 continue;
8409 if (!memcmp(ipatoe->addr, addr,
8410 (proto == QETH_PROT_IPV4)? 4:16) &&
8411 (ipatoe->mask_bits == mask_bits)){
8412 list_del(&ipatoe->entry);
8413 kfree(ipatoe);
8414 }
8415 }
8416 spin_unlock_irqrestore(&card->ip_lock, flags);
8417}
8418
8419static void
8420qeth_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
8421{
8422 int i, j;
8423 u8 octet;
8424
8425 for (i = 0; i < len; ++i){
8426 octet = addr[i];
8427 for (j = 7; j >= 0; --j){
8428 bits[i*8 + j] = octet & 1;
8429 octet >>= 1;
8430 }
8431 }
8432}
8433
8434static int
8435qeth_is_addr_covered_by_ipato(struct qeth_card *card, struct qeth_ipaddr *addr)
8436{
8437 struct qeth_ipato_entry *ipatoe;
8438 u8 addr_bits[128] = {0, };
8439 u8 ipatoe_bits[128] = {0, };
8440 int rc = 0;
8441
8442 if (!card->ipato.enabled)
8443 return 0;
8444
8445 qeth_convert_addr_to_bits((u8 *) &addr->u, addr_bits,
8446 (addr->proto == QETH_PROT_IPV4)? 4:16);
8447 list_for_each_entry(ipatoe, &card->ipato.entries, entry){
8448 if (addr->proto != ipatoe->proto)
8449 continue;
8450 qeth_convert_addr_to_bits(ipatoe->addr, ipatoe_bits,
8451 (ipatoe->proto==QETH_PROT_IPV4) ?
8452 4:16);
8453 if (addr->proto == QETH_PROT_IPV4)
8454 rc = !memcmp(addr_bits, ipatoe_bits,
8455 min(32, ipatoe->mask_bits));
8456 else
8457 rc = !memcmp(addr_bits, ipatoe_bits,
8458 min(128, ipatoe->mask_bits));
8459 if (rc)
8460 break;
8461 }
8462 /* invert? */
8463 if ((addr->proto == QETH_PROT_IPV4) && card->ipato.invert4)
8464 rc = !rc;
8465 else if ((addr->proto == QETH_PROT_IPV6) && card->ipato.invert6)
8466 rc = !rc;
8467
8468 return rc;
8469}
8470
8471/*
8472 * VIPA related functions
8473 */
8474int
8475qeth_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
8476 const u8 *addr)
8477{
8478 struct qeth_ipaddr *ipaddr;
8479 unsigned long flags;
8480 int rc = 0;
8481
8482 ipaddr = qeth_get_addr_buffer(proto);
8483 if (ipaddr){
8484 if (proto == QETH_PROT_IPV4){
8485 QETH_DBF_TEXT(trace, 2, "addvipa4");
8486 memcpy(&ipaddr->u.a4.addr, addr, 4);
8487 ipaddr->u.a4.mask = 0;
8488#ifdef CONFIG_QETH_IPV6
8489 } else if (proto == QETH_PROT_IPV6){
8490 QETH_DBF_TEXT(trace, 2, "addvipa6");
8491 memcpy(&ipaddr->u.a6.addr, addr, 16);
8492 ipaddr->u.a6.pfxlen = 0;
8493#endif
8494 }
8495 ipaddr->type = QETH_IP_TYPE_VIPA;
8496 ipaddr->set_flags = QETH_IPA_SETIP_VIPA_FLAG;
8497 ipaddr->del_flags = QETH_IPA_DELIP_VIPA_FLAG;
8498 } else
8499 return -ENOMEM;
8500 spin_lock_irqsave(&card->ip_lock, flags);
8501 if (__qeth_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
8502 __qeth_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
8503 rc = -EEXIST;
8504 spin_unlock_irqrestore(&card->ip_lock, flags);
8505 if (rc){
8506 PRINT_WARN("Cannot add VIPA. Address already exists!\n");
8507 return rc;
8508 }
8509 if (!qeth_add_ip(card, ipaddr))
8510 kfree(ipaddr);
8511 qeth_set_ip_addr_list(card);
8512 return rc;
8513}
8514
8515void
8516qeth_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
8517 const u8 *addr)
8518{
8519 struct qeth_ipaddr *ipaddr;
8520
8521 ipaddr = qeth_get_addr_buffer(proto);
8522 if (ipaddr){
8523 if (proto == QETH_PROT_IPV4){
8524 QETH_DBF_TEXT(trace, 2, "delvipa4");
8525 memcpy(&ipaddr->u.a4.addr, addr, 4);
8526 ipaddr->u.a4.mask = 0;
8527#ifdef CONFIG_QETH_IPV6
8528 } else if (proto == QETH_PROT_IPV6){
8529 QETH_DBF_TEXT(trace, 2, "delvipa6");
8530 memcpy(&ipaddr->u.a6.addr, addr, 16);
8531 ipaddr->u.a6.pfxlen = 0;
8532#endif
8533 }
8534 ipaddr->type = QETH_IP_TYPE_VIPA;
8535 } else
8536 return;
8537 if (!qeth_delete_ip(card, ipaddr))
8538 kfree(ipaddr);
8539 qeth_set_ip_addr_list(card);
8540}
8541
8542/*
8543 * proxy ARP related functions
8544 */
8545int
8546qeth_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
8547 const u8 *addr)
8548{
8549 struct qeth_ipaddr *ipaddr;
8550 unsigned long flags;
8551 int rc = 0;
8552
8553 ipaddr = qeth_get_addr_buffer(proto);
8554 if (ipaddr){
8555 if (proto == QETH_PROT_IPV4){
8556 QETH_DBF_TEXT(trace, 2, "addrxip4");
8557 memcpy(&ipaddr->u.a4.addr, addr, 4);
8558 ipaddr->u.a4.mask = 0;
8559#ifdef CONFIG_QETH_IPV6
8560 } else if (proto == QETH_PROT_IPV6){
8561 QETH_DBF_TEXT(trace, 2, "addrxip6");
8562 memcpy(&ipaddr->u.a6.addr, addr, 16);
8563 ipaddr->u.a6.pfxlen = 0;
8564#endif
8565 }
8566 ipaddr->type = QETH_IP_TYPE_RXIP;
8567 ipaddr->set_flags = QETH_IPA_SETIP_TAKEOVER_FLAG;
8568 ipaddr->del_flags = 0;
8569 } else
8570 return -ENOMEM;
8571 spin_lock_irqsave(&card->ip_lock, flags);
8572 if (__qeth_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
8573 __qeth_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
8574 rc = -EEXIST;
8575 spin_unlock_irqrestore(&card->ip_lock, flags);
8576 if (rc){
8577 PRINT_WARN("Cannot add RXIP. Address already exists!\n");
8578 return rc;
8579 }
8580 if (!qeth_add_ip(card, ipaddr))
8581 kfree(ipaddr);
8582 qeth_set_ip_addr_list(card);
8583 return 0;
8584}
8585
8586void
8587qeth_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
8588 const u8 *addr)
8589{
8590 struct qeth_ipaddr *ipaddr;
8591
8592 ipaddr = qeth_get_addr_buffer(proto);
8593 if (ipaddr){
8594 if (proto == QETH_PROT_IPV4){
8595 QETH_DBF_TEXT(trace, 2, "addrxip4");
8596 memcpy(&ipaddr->u.a4.addr, addr, 4);
8597 ipaddr->u.a4.mask = 0;
8598#ifdef CONFIG_QETH_IPV6
8599 } else if (proto == QETH_PROT_IPV6){
8600 QETH_DBF_TEXT(trace, 2, "addrxip6");
8601 memcpy(&ipaddr->u.a6.addr, addr, 16);
8602 ipaddr->u.a6.pfxlen = 0;
8603#endif
8604 }
8605 ipaddr->type = QETH_IP_TYPE_RXIP;
8606 } else
8607 return;
8608 if (!qeth_delete_ip(card, ipaddr))
8609 kfree(ipaddr);
8610 qeth_set_ip_addr_list(card);
8611}
8612
8613/**
8614 * IP event handler
8615 */
8616static int
8617qeth_ip_event(struct notifier_block *this,
8618 unsigned long event,void *ptr)
8619{
8620 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
8621 struct net_device *dev =(struct net_device *) ifa->ifa_dev->dev;
8622 struct qeth_ipaddr *addr;
8623 struct qeth_card *card;
8624
8625 if (dev->nd_net != &init_net)
8626 return NOTIFY_DONE;
8627
8628 QETH_DBF_TEXT(trace,3,"ipevent");
8629 card = qeth_get_card_from_dev(dev);
8630 if (!card)
8631 return NOTIFY_DONE;
8632 if (card->options.layer2)
8633 return NOTIFY_DONE;
8634
8635 addr = qeth_get_addr_buffer(QETH_PROT_IPV4);
8636 if (addr != NULL) {
8637 addr->u.a4.addr = ifa->ifa_address;
8638 addr->u.a4.mask = ifa->ifa_mask;
8639 addr->type = QETH_IP_TYPE_NORMAL;
8640 } else
8641 goto out;
8642
8643 switch(event) {
8644 case NETDEV_UP:
8645 if (!qeth_add_ip(card, addr))
8646 kfree(addr);
8647 break;
8648 case NETDEV_DOWN:
8649 if (!qeth_delete_ip(card, addr))
8650 kfree(addr);
8651 break;
8652 default:
8653 break;
8654 }
8655 qeth_set_ip_addr_list(card);
8656out:
8657 return NOTIFY_DONE;
8658}
8659
8660static struct notifier_block qeth_ip_notifier = {
8661 qeth_ip_event,
8662 NULL,
8663};
8664
8665#ifdef CONFIG_QETH_IPV6
8666/**
8667 * IPv6 event handler
8668 */
8669static int
8670qeth_ip6_event(struct notifier_block *this,
8671 unsigned long event,void *ptr)
8672{
8673
8674 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
8675 struct net_device *dev = (struct net_device *)ifa->idev->dev;
8676 struct qeth_ipaddr *addr;
8677 struct qeth_card *card;
8678
8679 QETH_DBF_TEXT(trace,3,"ip6event");
8680
8681 card = qeth_get_card_from_dev(dev);
8682 if (!card)
8683 return NOTIFY_DONE;
8684 if (!qeth_is_supported(card, IPA_IPV6))
8685 return NOTIFY_DONE;
8686
8687 addr = qeth_get_addr_buffer(QETH_PROT_IPV6);
8688 if (addr != NULL) {
8689 memcpy(&addr->u.a6.addr, &ifa->addr, sizeof(struct in6_addr));
8690 addr->u.a6.pfxlen = ifa->prefix_len;
8691 addr->type = QETH_IP_TYPE_NORMAL;
8692 } else
8693 goto out;
8694
8695 switch(event) {
8696 case NETDEV_UP:
8697 if (!qeth_add_ip(card, addr))
8698 kfree(addr);
8699 break;
8700 case NETDEV_DOWN:
8701 if (!qeth_delete_ip(card, addr))
8702 kfree(addr);
8703 break;
8704 default:
8705 break;
8706 }
8707 qeth_set_ip_addr_list(card);
8708out:
8709 return NOTIFY_DONE;
8710}
8711
8712static struct notifier_block qeth_ip6_notifier = {
8713 qeth_ip6_event,
8714 NULL,
8715};
8716#endif
8717
8718static int
8719__qeth_reboot_event_card(struct device *dev, void *data)
8720{
8721 struct qeth_card *card;
8722
8723 card = (struct qeth_card *) dev->driver_data;
8724 qeth_clear_ip_list(card, 0, 0);
8725 qeth_qdio_clear_card(card, 0);
8726 qeth_clear_qdio_buffers(card);
8727 return 0;
8728}
8729
8730static int
8731qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
8732{
8733 int ret;
8734
8735 ret = driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
8736 __qeth_reboot_event_card);
8737 return ret ? NOTIFY_BAD : NOTIFY_DONE;
8738}
8739
8740
8741static struct notifier_block qeth_reboot_notifier = {
8742 qeth_reboot_event,
8743 NULL,
8744};
8745
8746static int
8747qeth_register_notifiers(void)
8748{
8749 int r;
8750
8751 QETH_DBF_TEXT(trace,5,"regnotif");
8752 if ((r = register_reboot_notifier(&qeth_reboot_notifier)))
8753 return r;
8754 if ((r = register_inetaddr_notifier(&qeth_ip_notifier)))
8755 goto out_reboot;
8756#ifdef CONFIG_QETH_IPV6
8757 if ((r = register_inet6addr_notifier(&qeth_ip6_notifier)))
8758 goto out_ipv4;
8759#endif
8760 return 0;
8761
8762#ifdef CONFIG_QETH_IPV6
8763out_ipv4:
8764 unregister_inetaddr_notifier(&qeth_ip_notifier);
8765#endif
8766out_reboot:
8767 unregister_reboot_notifier(&qeth_reboot_notifier);
8768 return r;
8769}
8770
8771/**
8772 * unregister all event notifiers
8773 */
8774static void
8775qeth_unregister_notifiers(void)
8776{
8777
8778 QETH_DBF_TEXT(trace,5,"unregnot");
8779 BUG_ON(unregister_reboot_notifier(&qeth_reboot_notifier));
8780 BUG_ON(unregister_inetaddr_notifier(&qeth_ip_notifier));
8781#ifdef CONFIG_QETH_IPV6
8782 BUG_ON(unregister_inet6addr_notifier(&qeth_ip6_notifier));
8783#endif /* QETH_IPV6 */
8784
8785}
8786
8787#ifdef CONFIG_QETH_IPV6
8788static int
8789qeth_ipv6_init(void)
8790{
8791 qeth_old_arp_constructor = arp_tbl.constructor;
8792 write_lock_bh(&arp_tbl.lock);
8793 arp_tbl.constructor = qeth_arp_constructor;
8794 write_unlock_bh(&arp_tbl.lock);
8795
8796 arp_direct_ops = (struct neigh_ops*)
8797 kmalloc(sizeof(struct neigh_ops), GFP_KERNEL);
8798 if (!arp_direct_ops)
8799 return -ENOMEM;
8800
8801 memcpy(arp_direct_ops, &arp_direct_ops_template,
8802 sizeof(struct neigh_ops));
8803
8804 return 0;
8805}
8806
8807static void
8808qeth_ipv6_uninit(void)
8809{
8810 write_lock_bh(&arp_tbl.lock);
8811 arp_tbl.constructor = qeth_old_arp_constructor;
8812 write_unlock_bh(&arp_tbl.lock);
8813 kfree(arp_direct_ops);
8814}
8815#endif /* CONFIG_QETH_IPV6 */
8816
8817static void
8818qeth_sysfs_unregister(void)
8819{
8820 s390_root_dev_unregister(qeth_root_dev);
8821 qeth_remove_driver_attributes();
8822 ccw_driver_unregister(&qeth_ccw_driver);
8823 ccwgroup_driver_unregister(&qeth_ccwgroup_driver);
8824}
8825
8826/**
8827 * register qeth at sysfs
8828 */
8829static int
8830qeth_sysfs_register(void)
8831{
8832 int rc;
8833
8834 rc = ccwgroup_driver_register(&qeth_ccwgroup_driver);
8835 if (rc)
8836 goto out;
8837
8838 rc = ccw_driver_register(&qeth_ccw_driver);
8839 if (rc)
8840 goto out_ccw_driver;
8841
8842 rc = qeth_create_driver_attributes();
8843 if (rc)
8844 goto out_qeth_attr;
8845
8846 qeth_root_dev = s390_root_dev_register("qeth");
8847 rc = IS_ERR(qeth_root_dev) ? PTR_ERR(qeth_root_dev) : 0;
8848 if (!rc)
8849 goto out;
8850
8851 qeth_remove_driver_attributes();
8852out_qeth_attr:
8853 ccw_driver_unregister(&qeth_ccw_driver);
8854out_ccw_driver:
8855 ccwgroup_driver_unregister(&qeth_ccwgroup_driver);
8856out:
8857 return rc;
8858}
8859
8860/***
8861 * init function
8862 */
8863static int __init
8864qeth_init(void)
8865{
8866 int rc;
8867
8868 PRINT_INFO("loading %s\n", version);
8869
8870 INIT_LIST_HEAD(&qeth_card_list.list);
8871 INIT_LIST_HEAD(&qeth_notify_list);
8872 spin_lock_init(&qeth_notify_lock);
8873 rwlock_init(&qeth_card_list.rwlock);
8874
8875 rc = qeth_register_dbf_views();
8876 if (rc)
8877 goto out_err;
8878
8879 rc = qeth_sysfs_register();
8880 if (rc)
8881 goto out_dbf;
8882
8883#ifdef CONFIG_QETH_IPV6
8884 rc = qeth_ipv6_init();
8885 if (rc) {
8886 PRINT_ERR("Out of memory during ipv6 init code = %d\n", rc);
8887 goto out_sysfs;
8888 }
8889#endif /* QETH_IPV6 */
8890 rc = qeth_register_notifiers();
8891 if (rc)
8892 goto out_ipv6;
8893 rc = qeth_create_procfs_entries();
8894 if (rc)
8895 goto out_notifiers;
8896
8897 return rc;
8898
8899out_notifiers:
8900 qeth_unregister_notifiers();
8901out_ipv6:
8902#ifdef CONFIG_QETH_IPV6
8903 qeth_ipv6_uninit();
8904out_sysfs:
8905#endif /* QETH_IPV6 */
8906 qeth_sysfs_unregister();
8907out_dbf:
8908 qeth_unregister_dbf_views();
8909out_err:
8910 PRINT_ERR("Initialization failed with code %d\n", rc);
8911 return rc;
8912}
8913
8914static void
8915__exit qeth_exit(void)
8916{
8917 struct qeth_card *card, *tmp;
8918 unsigned long flags;
8919
8920 QETH_DBF_TEXT(trace,1, "cleanup.");
8921
8922 /*
8923 * Weed would not need to clean up our devices here, because the
8924 * common device layer calls qeth_remove_device for each device
8925 * as soon as we unregister our driver (done in qeth_sysfs_unregister).
8926 * But we do cleanup here so we can do a "soft" shutdown of our cards.
8927 * qeth_remove_device called by the common device layer would otherwise
8928 * do a "hard" shutdown (card->use_hard_stop is set to one in
8929 * qeth_remove_device).
8930 */
8931again:
8932 read_lock_irqsave(&qeth_card_list.rwlock, flags);
8933 list_for_each_entry_safe(card, tmp, &qeth_card_list.list, list){
8934 read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
8935 qeth_set_offline(card->gdev);
8936 qeth_remove_device(card->gdev);
8937 goto again;
8938 }
8939 read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
8940#ifdef CONFIG_QETH_IPV6
8941 qeth_ipv6_uninit();
8942#endif
8943 qeth_unregister_notifiers();
8944 qeth_remove_procfs_entries();
8945 qeth_sysfs_unregister();
8946 qeth_unregister_dbf_views();
8947 printk("qeth: removed\n");
8948}
8949
8950EXPORT_SYMBOL(qeth_osn_register);
8951EXPORT_SYMBOL(qeth_osn_deregister);
8952EXPORT_SYMBOL(qeth_osn_assist);
8953module_init(qeth_init);
8954module_exit(qeth_exit);
8955MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
8956MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \
8957 "Copyright 2000,2003 IBM Corporation\n");
8958
8959MODULE_LICENSE("GPL");
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
deleted file mode 100644
index f29a4bc4f6f2..000000000000
--- a/drivers/s390/net/qeth_mpc.c
+++ /dev/null
@@ -1,269 +0,0 @@
1/*
2 * linux/drivers/s390/net/qeth_mpc.c
3 *
4 * Linux on zSeries OSA Express and HiperSockets support
5 *
6 * Copyright 2000,2003 IBM Corporation
7 * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
8 * Thomas Spatzier <tspat@de.ibm.com>
9 *
10 */
11#include <asm/cio.h>
12#include "qeth_mpc.h"
13
14unsigned char IDX_ACTIVATE_READ[]={
15 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
16 0x19,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
17 0x00,0x00,0x00,0x00, 0x00,0x00,0xc8,0xc1,
18 0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00,
19 0x00,0x00
20};
21
22unsigned char IDX_ACTIVATE_WRITE[]={
23 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
24 0x15,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
25 0xff,0xff,0x00,0x00, 0x00,0x00,0xc8,0xc1,
26 0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00,
27 0x00,0x00
28};
29
30unsigned char CM_ENABLE[]={
31 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x01,
32 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x63,
33 0x10,0x00,0x00,0x01,
34 0x00,0x00,0x00,0x00,
35 0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00,
36 0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x23,
37 0x00,0x00,0x23,0x05, 0x00,0x00,0x00,0x00,
38 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
39 0x01,0x00,0x00,0x23, 0x00,0x00,0x00,0x40,
40 0x00,0x0c,0x41,0x02, 0x00,0x17,0x00,0x00,
41 0x00,0x00,0x00,0x00,
42 0x00,0x0b,0x04,0x01,
43 0x7e,0x04,0x05,0x00, 0x01,0x01,0x0f,
44 0x00,
45 0x0c,0x04,0x02,0xff, 0xff,0xff,0xff,0xff,
46 0xff,0xff,0xff
47};
48
49unsigned char CM_SETUP[]={
50 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x02,
51 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x64,
52 0x10,0x00,0x00,0x01,
53 0x00,0x00,0x00,0x00,
54 0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00,
55 0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x24,
56 0x00,0x00,0x24,0x05, 0x00,0x00,0x00,0x00,
57 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
58 0x01,0x00,0x00,0x24, 0x00,0x00,0x00,0x40,
59 0x00,0x0c,0x41,0x04, 0x00,0x18,0x00,0x00,
60 0x00,0x00,0x00,0x00,
61 0x00,0x09,0x04,0x04,
62 0x05,0x00,0x01,0x01, 0x11,
63 0x00,0x09,0x04,
64 0x05,0x05,0x00,0x00, 0x00,0x00,
65 0x00,0x06,
66 0x04,0x06,0xc8,0x00
67};
68
69unsigned char ULP_ENABLE[]={
70 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x03,
71 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6b,
72 0x10,0x00,0x00,0x01,
73 0x00,0x00,0x00,0x00,
74 0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x01,
75 0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x2b,
76 0x00,0x00,0x2b,0x05, 0x20,0x01,0x00,0x00,
77 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
78 0x01,0x00,0x00,0x2b, 0x00,0x00,0x00,0x40,
79 0x00,0x0c,0x41,0x02, 0x00,0x1f,0x00,0x00,
80 0x00,0x00,0x00,0x00,
81 0x00,0x0b,0x04,0x01,
82 0x03,0x04,0x05,0x00, 0x01,0x01,0x12,
83 0x00,
84 0x14,0x04,0x0a,0x00, 0x20,0x00,0x00,0xff,
85 0xff,0x00,0x08,0xc8, 0xe8,0xc4,0xf1,0xc7,
86 0xf1,0x00,0x00
87};
88
89unsigned char ULP_SETUP[]={
90 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x04,
91 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6c,
92 0x10,0x00,0x00,0x01,
93 0x00,0x00,0x00,0x00,
94 0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x02,
95 0x00,0x00,0x00,0x01, 0x00,0x24,0x00,0x2c,
96 0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00,
97 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
98 0x01,0x00,0x00,0x2c, 0x00,0x00,0x00,0x40,
99 0x00,0x0c,0x41,0x04, 0x00,0x20,0x00,0x00,
100 0x00,0x00,0x00,0x00,
101 0x00,0x09,0x04,0x04,
102 0x05,0x00,0x01,0x01, 0x14,
103 0x00,0x09,0x04,
104 0x05,0x05,0x30,0x01, 0x00,0x00,
105 0x00,0x06,
106 0x04,0x06,0x40,0x00,
107 0x00,0x08,0x04,0x0b,
108 0x00,0x00,0x00,0x00
109};
110
111unsigned char DM_ACT[]={
112 0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x05,
113 0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x55,
114 0x10,0x00,0x00,0x01,
115 0x00,0x00,0x00,0x00,
116 0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x03,
117 0x00,0x00,0x00,0x02, 0x00,0x24,0x00,0x15,
118 0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00,
119 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
120 0x01,0x00,0x00,0x15, 0x00,0x00,0x00,0x40,
121 0x00,0x0c,0x43,0x60, 0x00,0x09,0x00,0x00,
122 0x00,0x00,0x00,0x00,
123 0x00,0x09,0x04,0x04,
124 0x05,0x40,0x01,0x01, 0x00
125};
126
127unsigned char IPA_PDU_HEADER[]={
128 0x00,0xe0,0x00,0x00, 0x77,0x77,0x77,0x77,
129 0x00,0x00,0x00,0x14, 0x00,0x00,
130 (IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))/256,
131 (IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))%256,
132 0x10,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,
133 0xc1,0x03,0x00,0x01, 0x00,0x00,0x00,0x00,
134 0x00,0x00,0x00,0x00, 0x00,0x24,
135 sizeof(struct qeth_ipa_cmd)/256,
136 sizeof(struct qeth_ipa_cmd)%256,
137 0x00,
138 sizeof(struct qeth_ipa_cmd)/256,
139 sizeof(struct qeth_ipa_cmd)%256,
140 0x05,
141 0x77,0x77,0x77,0x77,
142 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
143 0x01,0x00,
144 sizeof(struct qeth_ipa_cmd)/256,
145 sizeof(struct qeth_ipa_cmd)%256,
146 0x00,0x00,0x00,0x40,
147};
148
149unsigned char WRITE_CCW[]={
150 0x01,CCW_FLAG_SLI,0,0,
151 0,0,0,0
152};
153
154unsigned char READ_CCW[]={
155 0x02,CCW_FLAG_SLI,0,0,
156 0,0,0,0
157};
158
159
160struct ipa_rc_msg {
161 enum qeth_ipa_return_codes rc;
162 char *msg;
163};
164
165static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
166 {IPA_RC_SUCCESS, "success"},
167 {IPA_RC_NOTSUPP, "Command not supported"},
168 {IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"},
169 {IPA_RC_UNKNOWN_ERROR, "IPA command failed - reason unknown"},
170 {IPA_RC_UNSUPPORTED_COMMAND, "Command not supported"},
171 {IPA_RC_DUP_IPV6_REMOTE,"ipv6 address already registered remote"},
172 {IPA_RC_DUP_IPV6_HOME, "ipv6 address already registered"},
173 {IPA_RC_UNREGISTERED_ADDR, "Address not registered"},
174 {IPA_RC_NO_ID_AVAILABLE, "No identifiers available"},
175 {IPA_RC_ID_NOT_FOUND, "Identifier not found"},
176 {IPA_RC_INVALID_IP_VERSION, "IP version incorrect"},
177 {IPA_RC_LAN_FRAME_MISMATCH, "LAN and frame mismatch"},
178 {IPA_RC_L2_UNSUPPORTED_CMD, "Unsupported layer 2 command"},
179 {IPA_RC_L2_DUP_MAC, "Duplicate MAC address"},
180 {IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"},
181 {IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"},
182 {IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"},
183 {IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"},
184 {IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"},
185 {IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"},
186 {IPA_RC_L2_VLAN_ID_NOT_FOUND, "L2 vlan id not found"},
187 {IPA_RC_DATA_MISMATCH, "Data field mismatch (v4/v6 mixed)"},
188 {IPA_RC_INVALID_MTU_SIZE, "Invalid MTU size"},
189 {IPA_RC_INVALID_LANTYPE, "Invalid LAN type"},
190 {IPA_RC_INVALID_LANNUM, "Invalid LAN num"},
191 {IPA_RC_DUPLICATE_IP_ADDRESS, "Address already registered"},
192 {IPA_RC_IP_ADDR_TABLE_FULL, "IP address table full"},
193 {IPA_RC_LAN_PORT_STATE_ERROR, "LAN port state error"},
194 {IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"},
195 {IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"},
196 {IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"},
197 {IPA_RC_MULTICAST_FULL, "No task available, multicast full"},
198 {IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"},
199 {IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"},
200 {IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"},
201 {IPA_RC_PRIMARY_ALREADY_DEFINED,"Primary already defined"},
202 {IPA_RC_SECOND_ALREADY_DEFINED, "Secondary already defined"},
203 {IPA_RC_INVALID_SETRTG_INDICATOR,"Invalid SETRTG indicator"},
204 {IPA_RC_MC_ADDR_ALREADY_DEFINED,"Multicast address already defined"},
205 {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
206 {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
207 {IPA_RC_FFFF, "Unknown Error"}
208};
209
210
211
212char *
213qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
214{
215 int x = 0;
216 qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) /
217 sizeof(struct ipa_rc_msg) - 1].rc = rc;
218 while(qeth_ipa_rc_msg[x].rc != rc)
219 x++;
220 return qeth_ipa_rc_msg[x].msg;
221}
222
223
224struct ipa_cmd_names {
225 enum qeth_ipa_cmds cmd;
226 char *name;
227};
228
229static struct ipa_cmd_names qeth_ipa_cmd_names[] = {
230 {IPA_CMD_STARTLAN, "startlan"},
231 {IPA_CMD_STOPLAN, "stoplan"},
232 {IPA_CMD_SETVMAC, "setvmac"},
233 {IPA_CMD_DELVMAC, "delvmca"},
234 {IPA_CMD_SETGMAC, "setgmac"},
235 {IPA_CMD_DELGMAC, "delgmac"},
236 {IPA_CMD_SETVLAN, "setvlan"},
237 {IPA_CMD_DELVLAN, "delvlan"},
238 {IPA_CMD_SETCCID, "setccid"},
239 {IPA_CMD_DELCCID, "delccid"},
240 {IPA_CMD_MODCCID, "setip"},
241 {IPA_CMD_SETIP, "setip"},
242 {IPA_CMD_QIPASSIST, "qipassist"},
243 {IPA_CMD_SETASSPARMS, "setassparms"},
244 {IPA_CMD_SETIPM, "setipm"},
245 {IPA_CMD_DELIPM, "delipm"},
246 {IPA_CMD_SETRTG, "setrtg"},
247 {IPA_CMD_DELIP, "delip"},
248 {IPA_CMD_SETADAPTERPARMS, "setadapterparms"},
249 {IPA_CMD_SET_DIAG_ASS, "set_diag_ass"},
250 {IPA_CMD_CREATE_ADDR, "create_addr"},
251 {IPA_CMD_DESTROY_ADDR, "destroy_addr"},
252 {IPA_CMD_REGISTER_LOCAL_ADDR, "register_local_addr"},
253 {IPA_CMD_UNREGISTER_LOCAL_ADDR, "unregister_local_addr"},
254 {IPA_CMD_UNKNOWN, "unknown"},
255};
256
257char *
258qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
259{
260 int x = 0;
261 qeth_ipa_cmd_names[
262 sizeof(qeth_ipa_cmd_names)/
263 sizeof(struct ipa_cmd_names)-1].cmd = cmd;
264 while(qeth_ipa_cmd_names[x].cmd != cmd)
265 x++;
266 return qeth_ipa_cmd_names[x].name;
267}
268
269
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
deleted file mode 100644
index 46ecd03a597e..000000000000
--- a/drivers/s390/net/qeth_proc.c
+++ /dev/null
@@ -1,316 +0,0 @@
1/*
2 *
3 * linux/drivers/s390/net/qeth_fs.c
4 *
5 * Linux on zSeries OSA Express and HiperSockets support
6 * This file contains code related to procfs.
7 *
8 * Copyright 2000,2003 IBM Corporation
9 *
10 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
11 *
12 */
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/proc_fs.h>
16#include <linux/seq_file.h>
17#include <linux/list.h>
18#include <linux/rwsem.h>
19
20#include "qeth.h"
21#include "qeth_mpc.h"
22#include "qeth_fs.h"
23
24/***** /proc/qeth *****/
25#define QETH_PROCFILE_NAME "qeth"
26static struct proc_dir_entry *qeth_procfile;
27
28static int
29qeth_procfile_seq_match(struct device *dev, void *data)
30{
31 return(dev ? 1 : 0);
32}
33
34static void *
35qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
36{
37 struct device *dev = NULL;
38 loff_t nr = 0;
39
40 if (*offset == 0)
41 return SEQ_START_TOKEN;
42 while (1) {
43 dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
44 NULL, qeth_procfile_seq_match);
45 if (++nr == *offset)
46 break;
47 put_device(dev);
48 }
49 return dev;
50}
51
52static void
53qeth_procfile_seq_stop(struct seq_file *s, void* it)
54{
55}
56
57static void *
58qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
59{
60 struct device *prev, *next;
61
62 if (it == SEQ_START_TOKEN)
63 prev = NULL;
64 else
65 prev = (struct device *) it;
66 next = driver_find_device(&qeth_ccwgroup_driver.driver,
67 prev, NULL, qeth_procfile_seq_match);
68 (*offset)++;
69 return (void *) next;
70}
71
72static inline const char *
73qeth_get_router_str(struct qeth_card *card, int ipv)
74{
75 enum qeth_routing_types routing_type = NO_ROUTER;
76
77 if (ipv == 4) {
78 routing_type = card->options.route4.type;
79 } else {
80#ifdef CONFIG_QETH_IPV6
81 routing_type = card->options.route6.type;
82#else
83 return "n/a";
84#endif /* CONFIG_QETH_IPV6 */
85 }
86
87 switch (routing_type){
88 case PRIMARY_ROUTER:
89 return "pri";
90 case SECONDARY_ROUTER:
91 return "sec";
92 case MULTICAST_ROUTER:
93 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
94 return "mc+";
95 return "mc";
96 case PRIMARY_CONNECTOR:
97 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
98 return "p+c";
99 return "p.c";
100 case SECONDARY_CONNECTOR:
101 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
102 return "s+c";
103 return "s.c";
104 default: /* NO_ROUTER */
105 return "no";
106 }
107}
108
109static int
110qeth_procfile_seq_show(struct seq_file *s, void *it)
111{
112 struct device *device;
113 struct qeth_card *card;
114 char tmp[12]; /* for qeth_get_prioq_str */
115
116 if (it == SEQ_START_TOKEN){
117 seq_printf(s, "devices CHPID interface "
118 "cardtype port chksum prio-q'ing rtr4 "
119 "rtr6 fsz cnt\n");
120 seq_printf(s, "-------------------------- ----- ---------- "
121 "-------------- ---- ------ ---------- ---- "
122 "---- ----- -----\n");
123 } else {
124 device = (struct device *) it;
125 card = device->driver_data;
126 seq_printf(s, "%s/%s/%s x%02X %-10s %-14s %-4i ",
127 CARD_RDEV_ID(card),
128 CARD_WDEV_ID(card),
129 CARD_DDEV_ID(card),
130 card->info.chpid,
131 QETH_CARD_IFNAME(card),
132 qeth_get_cardname_short(card),
133 card->info.portno);
134 if (card->lan_online)
135 seq_printf(s, "%-6s %-10s %-4s %-4s %-5s %-5i\n",
136 qeth_get_checksum_str(card),
137 qeth_get_prioq_str(card, tmp),
138 qeth_get_router_str(card, 4),
139 qeth_get_router_str(card, 6),
140 qeth_get_bufsize_str(card),
141 card->qdio.in_buf_pool.buf_count);
142 else
143 seq_printf(s, " +++ LAN OFFLINE +++\n");
144 put_device(device);
145 }
146 return 0;
147}
148
149static const struct seq_operations qeth_procfile_seq_ops = {
150 .start = qeth_procfile_seq_start,
151 .stop = qeth_procfile_seq_stop,
152 .next = qeth_procfile_seq_next,
153 .show = qeth_procfile_seq_show,
154};
155
156static int
157qeth_procfile_open(struct inode *inode, struct file *file)
158{
159 return seq_open(file, &qeth_procfile_seq_ops);
160}
161
162static const struct file_operations qeth_procfile_fops = {
163 .owner = THIS_MODULE,
164 .open = qeth_procfile_open,
165 .read = seq_read,
166 .llseek = seq_lseek,
167 .release = seq_release,
168};
169
170/***** /proc/qeth_perf *****/
171#define QETH_PERF_PROCFILE_NAME "qeth_perf"
172static struct proc_dir_entry *qeth_perf_procfile;
173
174static int
175qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
176{
177 struct device *device;
178 struct qeth_card *card;
179
180
181 if (it == SEQ_START_TOKEN)
182 return 0;
183
184 device = (struct device *) it;
185 card = device->driver_data;
186 seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
187 CARD_RDEV_ID(card),
188 CARD_WDEV_ID(card),
189 CARD_DDEV_ID(card),
190 QETH_CARD_IFNAME(card)
191 );
192 if (!card->options.performance_stats)
193 seq_printf(s, "Performance statistics are deactivated.\n");
194 seq_printf(s, " Skb's/buffers received : %lu/%u\n"
195 " Skb's/buffers sent : %lu/%u\n\n",
196 card->stats.rx_packets -
197 card->perf_stats.initial_rx_packets,
198 card->perf_stats.bufs_rec,
199 card->stats.tx_packets -
200 card->perf_stats.initial_tx_packets,
201 card->perf_stats.bufs_sent
202 );
203 seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n"
204 " Skb's/buffers sent with packing : %u/%u\n\n",
205 card->stats.tx_packets - card->perf_stats.initial_tx_packets
206 - card->perf_stats.skbs_sent_pack,
207 card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
208 card->perf_stats.skbs_sent_pack,
209 card->perf_stats.bufs_sent_pack
210 );
211 seq_printf(s, " Skbs sent in SG mode : %u\n"
212 " Skb fragments sent in SG mode : %u\n\n",
213 card->perf_stats.sg_skbs_sent,
214 card->perf_stats.sg_frags_sent);
215 seq_printf(s, " Skbs received in SG mode : %u\n"
216 " Skb fragments received in SG mode : %u\n"
217 " Page allocations for rx SG mode : %u\n\n",
218 card->perf_stats.sg_skbs_rx,
219 card->perf_stats.sg_frags_rx,
220 card->perf_stats.sg_alloc_page_rx);
221 seq_printf(s, " large_send tx (in Kbytes) : %u\n"
222 " large_send count : %u\n\n",
223 card->perf_stats.large_send_bytes >> 10,
224 card->perf_stats.large_send_cnt);
225 seq_printf(s, " Packing state changes no pkg.->packing : %u/%u\n"
226 " Watermarks L/H : %i/%i\n"
227 " Current buffer usage (outbound q's) : "
228 "%i/%i/%i/%i\n\n",
229 card->perf_stats.sc_dp_p, card->perf_stats.sc_p_dp,
230 QETH_LOW_WATERMARK_PACK, QETH_HIGH_WATERMARK_PACK,
231 atomic_read(&card->qdio.out_qs[0]->used_buffers),
232 (card->qdio.no_out_queues > 1)?
233 atomic_read(&card->qdio.out_qs[1]->used_buffers)
234 : 0,
235 (card->qdio.no_out_queues > 2)?
236 atomic_read(&card->qdio.out_qs[2]->used_buffers)
237 : 0,
238 (card->qdio.no_out_queues > 3)?
239 atomic_read(&card->qdio.out_qs[3]->used_buffers)
240 : 0
241 );
242 seq_printf(s, " Inbound handler time (in us) : %u\n"
243 " Inbound handler count : %u\n"
244 " Inbound do_QDIO time (in us) : %u\n"
245 " Inbound do_QDIO count : %u\n\n"
246 " Outbound handler time (in us) : %u\n"
247 " Outbound handler count : %u\n\n"
248 " Outbound time (in us, incl QDIO) : %u\n"
249 " Outbound count : %u\n"
250 " Outbound do_QDIO time (in us) : %u\n"
251 " Outbound do_QDIO count : %u\n\n",
252 card->perf_stats.inbound_time,
253 card->perf_stats.inbound_cnt,
254 card->perf_stats.inbound_do_qdio_time,
255 card->perf_stats.inbound_do_qdio_cnt,
256 card->perf_stats.outbound_handler_time,
257 card->perf_stats.outbound_handler_cnt,
258 card->perf_stats.outbound_time,
259 card->perf_stats.outbound_cnt,
260 card->perf_stats.outbound_do_qdio_time,
261 card->perf_stats.outbound_do_qdio_cnt
262 );
263 put_device(device);
264 return 0;
265}
266
267static const struct seq_operations qeth_perf_procfile_seq_ops = {
268 .start = qeth_procfile_seq_start,
269 .stop = qeth_procfile_seq_stop,
270 .next = qeth_procfile_seq_next,
271 .show = qeth_perf_procfile_seq_show,
272};
273
274static int
275qeth_perf_procfile_open(struct inode *inode, struct file *file)
276{
277 return seq_open(file, &qeth_perf_procfile_seq_ops);
278}
279
280static const struct file_operations qeth_perf_procfile_fops = {
281 .owner = THIS_MODULE,
282 .open = qeth_perf_procfile_open,
283 .read = seq_read,
284 .llseek = seq_lseek,
285 .release = seq_release,
286};
287
288int __init
289qeth_create_procfs_entries(void)
290{
291 qeth_procfile = create_proc_entry(QETH_PROCFILE_NAME,
292 S_IFREG | 0444, NULL);
293 if (qeth_procfile)
294 qeth_procfile->proc_fops = &qeth_procfile_fops;
295
296 qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME,
297 S_IFREG | 0444, NULL);
298 if (qeth_perf_procfile)
299 qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
300
301 if (qeth_procfile &&
302 qeth_perf_procfile)
303 return 0;
304 else
305 return -ENOMEM;
306}
307
308void __exit
309qeth_remove_procfs_entries(void)
310{
311 if (qeth_procfile)
312 remove_proc_entry(QETH_PROCFILE_NAME, NULL);
313 if (qeth_perf_procfile)
314 remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL);
315}
316
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
deleted file mode 100644
index 2cc3f3a0e393..000000000000
--- a/drivers/s390/net/qeth_sys.c
+++ /dev/null
@@ -1,1858 +0,0 @@
1/*
2 *
3 * linux/drivers/s390/net/qeth_sys.c
4 *
5 * Linux on zSeries OSA Express and HiperSockets support
6 * This file contains code related to sysfs.
7 *
8 * Copyright 2000,2003 IBM Corporation
9 *
10 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
11 * Frank Pavlic <fpavlic@de.ibm.com>
12 *
13 */
14#include <linux/list.h>
15#include <linux/rwsem.h>
16
17#include <asm/ebcdic.h>
18
19#include "qeth.h"
20#include "qeth_mpc.h"
21#include "qeth_fs.h"
22
23/*****************************************************************************/
24/* */
25/* /sys-fs stuff UNDER DEVELOPMENT !!! */
26/* */
27/*****************************************************************************/
28//low/high watermark
29
30static ssize_t
31qeth_dev_state_show(struct device *dev, struct device_attribute *attr, char *buf)
32{
33 struct qeth_card *card = dev->driver_data;
34 if (!card)
35 return -EINVAL;
36
37 switch (card->state) {
38 case CARD_STATE_DOWN:
39 return sprintf(buf, "DOWN\n");
40 case CARD_STATE_HARDSETUP:
41 return sprintf(buf, "HARDSETUP\n");
42 case CARD_STATE_SOFTSETUP:
43 return sprintf(buf, "SOFTSETUP\n");
44 case CARD_STATE_UP:
45 if (card->lan_online)
46 return sprintf(buf, "UP (LAN ONLINE)\n");
47 else
48 return sprintf(buf, "UP (LAN OFFLINE)\n");
49 case CARD_STATE_RECOVER:
50 return sprintf(buf, "RECOVER\n");
51 default:
52 return sprintf(buf, "UNKNOWN\n");
53 }
54}
55
56static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
57
58static ssize_t
59qeth_dev_chpid_show(struct device *dev, struct device_attribute *attr, char *buf)
60{
61 struct qeth_card *card = dev->driver_data;
62 if (!card)
63 return -EINVAL;
64
65 return sprintf(buf, "%02X\n", card->info.chpid);
66}
67
68static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
69
70static ssize_t
71qeth_dev_if_name_show(struct device *dev, struct device_attribute *attr, char *buf)
72{
73 struct qeth_card *card = dev->driver_data;
74 if (!card)
75 return -EINVAL;
76 return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));
77}
78
79static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
80
81static ssize_t
82qeth_dev_card_type_show(struct device *dev, struct device_attribute *attr, char *buf)
83{
84 struct qeth_card *card = dev->driver_data;
85 if (!card)
86 return -EINVAL;
87
88 return sprintf(buf, "%s\n", qeth_get_cardname_short(card));
89}
90
91static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
92
93static ssize_t
94qeth_dev_portno_show(struct device *dev, struct device_attribute *attr, char *buf)
95{
96 struct qeth_card *card = dev->driver_data;
97 if (!card)
98 return -EINVAL;
99
100 return sprintf(buf, "%i\n", card->info.portno);
101}
102
103static ssize_t
104qeth_dev_portno_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
105{
106 struct qeth_card *card = dev->driver_data;
107 char *tmp;
108 unsigned int portno;
109
110 if (!card)
111 return -EINVAL;
112
113 if ((card->state != CARD_STATE_DOWN) &&
114 (card->state != CARD_STATE_RECOVER))
115 return -EPERM;
116
117 portno = simple_strtoul(buf, &tmp, 16);
118 if (portno > MAX_PORTNO){
119 PRINT_WARN("portno 0x%X is out of range\n", portno);
120 return -EINVAL;
121 }
122
123 card->info.portno = portno;
124 return count;
125}
126
127static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
128
129static ssize_t
130qeth_dev_portname_show(struct device *dev, struct device_attribute *attr, char *buf)
131{
132 struct qeth_card *card = dev->driver_data;
133 char portname[9] = {0, };
134
135 if (!card)
136 return -EINVAL;
137
138 if (card->info.portname_required) {
139 memcpy(portname, card->info.portname + 1, 8);
140 EBCASC(portname, 8);
141 return sprintf(buf, "%s\n", portname);
142 } else
143 return sprintf(buf, "no portname required\n");
144}
145
146static ssize_t
147qeth_dev_portname_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
148{
149 struct qeth_card *card = dev->driver_data;
150 char *tmp;
151 int i;
152
153 if (!card)
154 return -EINVAL;
155
156 if ((card->state != CARD_STATE_DOWN) &&
157 (card->state != CARD_STATE_RECOVER))
158 return -EPERM;
159
160 tmp = strsep((char **) &buf, "\n");
161 if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
162 return -EINVAL;
163
164 card->info.portname[0] = strlen(tmp);
165 /* for beauty reasons */
166 for (i = 1; i < 9; i++)
167 card->info.portname[i] = ' ';
168 strcpy(card->info.portname + 1, tmp);
169 ASCEBC(card->info.portname + 1, 8);
170
171 return count;
172}
173
174static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
175 qeth_dev_portname_store);
176
177static ssize_t
178qeth_dev_checksum_show(struct device *dev, struct device_attribute *attr, char *buf)
179{
180 struct qeth_card *card = dev->driver_data;
181
182 if (!card)
183 return -EINVAL;
184
185 return sprintf(buf, "%s checksumming\n", qeth_get_checksum_str(card));
186}
187
188static ssize_t
189qeth_dev_checksum_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
190{
191 struct qeth_card *card = dev->driver_data;
192 char *tmp;
193
194 if (!card)
195 return -EINVAL;
196
197 if ((card->state != CARD_STATE_DOWN) &&
198 (card->state != CARD_STATE_RECOVER))
199 return -EPERM;
200
201 tmp = strsep((char **) &buf, "\n");
202 if (!strcmp(tmp, "sw_checksumming"))
203 card->options.checksum_type = SW_CHECKSUMMING;
204 else if (!strcmp(tmp, "hw_checksumming"))
205 card->options.checksum_type = HW_CHECKSUMMING;
206 else if (!strcmp(tmp, "no_checksumming"))
207 card->options.checksum_type = NO_CHECKSUMMING;
208 else {
209 PRINT_WARN("Unknown checksumming type '%s'\n", tmp);
210 return -EINVAL;
211 }
212 return count;
213}
214
215static DEVICE_ATTR(checksumming, 0644, qeth_dev_checksum_show,
216 qeth_dev_checksum_store);
217
218static ssize_t
219qeth_dev_prioqing_show(struct device *dev, struct device_attribute *attr, char *buf)
220{
221 struct qeth_card *card = dev->driver_data;
222
223 if (!card)
224 return -EINVAL;
225
226 switch (card->qdio.do_prio_queueing) {
227 case QETH_PRIO_Q_ING_PREC:
228 return sprintf(buf, "%s\n", "by precedence");
229 case QETH_PRIO_Q_ING_TOS:
230 return sprintf(buf, "%s\n", "by type of service");
231 default:
232 return sprintf(buf, "always queue %i\n",
233 card->qdio.default_out_queue);
234 }
235}
236
237static ssize_t
238qeth_dev_prioqing_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
239{
240 struct qeth_card *card = dev->driver_data;
241 char *tmp;
242
243 if (!card)
244 return -EINVAL;
245
246 if ((card->state != CARD_STATE_DOWN) &&
247 (card->state != CARD_STATE_RECOVER))
248 return -EPERM;
249
250 /* check if 1920 devices are supported ,
251 * if though we have to permit priority queueing
252 */
253 if (card->qdio.no_out_queues == 1) {
254 PRINT_WARN("Priority queueing disabled due "
255 "to hardware limitations!\n");
256 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
257 return -EPERM;
258 }
259
260 tmp = strsep((char **) &buf, "\n");
261 if (!strcmp(tmp, "prio_queueing_prec"))
262 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
263 else if (!strcmp(tmp, "prio_queueing_tos"))
264 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
265 else if (!strcmp(tmp, "no_prio_queueing:0")) {
266 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
267 card->qdio.default_out_queue = 0;
268 } else if (!strcmp(tmp, "no_prio_queueing:1")) {
269 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
270 card->qdio.default_out_queue = 1;
271 } else if (!strcmp(tmp, "no_prio_queueing:2")) {
272 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
273 card->qdio.default_out_queue = 2;
274 } else if (!strcmp(tmp, "no_prio_queueing:3")) {
275 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
276 card->qdio.default_out_queue = 3;
277 } else if (!strcmp(tmp, "no_prio_queueing")) {
278 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
279 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
280 } else {
281 PRINT_WARN("Unknown queueing type '%s'\n", tmp);
282 return -EINVAL;
283 }
284 return count;
285}
286
287static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
288 qeth_dev_prioqing_store);
289
290static ssize_t
291qeth_dev_bufcnt_show(struct device *dev, struct device_attribute *attr, char *buf)
292{
293 struct qeth_card *card = dev->driver_data;
294
295 if (!card)
296 return -EINVAL;
297
298 return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);
299}
300
301static ssize_t
302qeth_dev_bufcnt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
303{
304 struct qeth_card *card = dev->driver_data;
305 char *tmp;
306 int cnt, old_cnt;
307 int rc;
308
309 if (!card)
310 return -EINVAL;
311
312 if ((card->state != CARD_STATE_DOWN) &&
313 (card->state != CARD_STATE_RECOVER))
314 return -EPERM;
315
316 old_cnt = card->qdio.in_buf_pool.buf_count;
317 cnt = simple_strtoul(buf, &tmp, 10);
318 cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
319 ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
320 if (old_cnt != cnt) {
321 if ((rc = qeth_realloc_buffer_pool(card, cnt)))
322 PRINT_WARN("Error (%d) while setting "
323 "buffer count.\n", rc);
324 }
325 return count;
326}
327
328static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
329 qeth_dev_bufcnt_store);
330
331static ssize_t
332qeth_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route,
333 char *buf)
334{
335 switch (route->type) {
336 case PRIMARY_ROUTER:
337 return sprintf(buf, "%s\n", "primary router");
338 case SECONDARY_ROUTER:
339 return sprintf(buf, "%s\n", "secondary router");
340 case MULTICAST_ROUTER:
341 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
342 return sprintf(buf, "%s\n", "multicast router+");
343 else
344 return sprintf(buf, "%s\n", "multicast router");
345 case PRIMARY_CONNECTOR:
346 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
347 return sprintf(buf, "%s\n", "primary connector+");
348 else
349 return sprintf(buf, "%s\n", "primary connector");
350 case SECONDARY_CONNECTOR:
351 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
352 return sprintf(buf, "%s\n", "secondary connector+");
353 else
354 return sprintf(buf, "%s\n", "secondary connector");
355 default:
356 return sprintf(buf, "%s\n", "no");
357 }
358}
359
360static ssize_t
361qeth_dev_route4_show(struct device *dev, struct device_attribute *attr, char *buf)
362{
363 struct qeth_card *card = dev->driver_data;
364
365 if (!card)
366 return -EINVAL;
367
368 return qeth_dev_route_show(card, &card->options.route4, buf);
369}
370
371static ssize_t
372qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
373 enum qeth_prot_versions prot, const char *buf, size_t count)
374{
375 enum qeth_routing_types old_route_type = route->type;
376 char *tmp;
377 int rc;
378
379 tmp = strsep((char **) &buf, "\n");
380
381 if (!strcmp(tmp, "no_router")){
382 route->type = NO_ROUTER;
383 } else if (!strcmp(tmp, "primary_connector")) {
384 route->type = PRIMARY_CONNECTOR;
385 } else if (!strcmp(tmp, "secondary_connector")) {
386 route->type = SECONDARY_CONNECTOR;
387 } else if (!strcmp(tmp, "primary_router")) {
388 route->type = PRIMARY_ROUTER;
389 } else if (!strcmp(tmp, "secondary_router")) {
390 route->type = SECONDARY_ROUTER;
391 } else if (!strcmp(tmp, "multicast_router")) {
392 route->type = MULTICAST_ROUTER;
393 } else {
394 PRINT_WARN("Invalid routing type '%s'.\n", tmp);
395 return -EINVAL;
396 }
397 if (((card->state == CARD_STATE_SOFTSETUP) ||
398 (card->state == CARD_STATE_UP)) &&
399 (old_route_type != route->type)){
400 if (prot == QETH_PROT_IPV4)
401 rc = qeth_setrouting_v4(card);
402 else if (prot == QETH_PROT_IPV6)
403 rc = qeth_setrouting_v6(card);
404 }
405 return count;
406}
407
408static ssize_t
409qeth_dev_route4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
410{
411 struct qeth_card *card = dev->driver_data;
412
413 if (!card)
414 return -EINVAL;
415
416 return qeth_dev_route_store(card, &card->options.route4,
417 QETH_PROT_IPV4, buf, count);
418}
419
420static DEVICE_ATTR(route4, 0644, qeth_dev_route4_show, qeth_dev_route4_store);
421
422#ifdef CONFIG_QETH_IPV6
423static ssize_t
424qeth_dev_route6_show(struct device *dev, struct device_attribute *attr, char *buf)
425{
426 struct qeth_card *card = dev->driver_data;
427
428 if (!card)
429 return -EINVAL;
430
431 if (!qeth_is_supported(card, IPA_IPV6))
432 return sprintf(buf, "%s\n", "n/a");
433
434 return qeth_dev_route_show(card, &card->options.route6, buf);
435}
436
437static ssize_t
438qeth_dev_route6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
439{
440 struct qeth_card *card = dev->driver_data;
441
442 if (!card)
443 return -EINVAL;
444
445 if (!qeth_is_supported(card, IPA_IPV6)){
446 PRINT_WARN("IPv6 not supported for interface %s.\n"
447 "Routing status no changed.\n",
448 QETH_CARD_IFNAME(card));
449 return -ENOTSUPP;
450 }
451
452 return qeth_dev_route_store(card, &card->options.route6,
453 QETH_PROT_IPV6, buf, count);
454}
455
456static DEVICE_ATTR(route6, 0644, qeth_dev_route6_show, qeth_dev_route6_store);
457#endif
458
459static ssize_t
460qeth_dev_add_hhlen_show(struct device *dev, struct device_attribute *attr, char *buf)
461{
462 struct qeth_card *card = dev->driver_data;
463
464 if (!card)
465 return -EINVAL;
466
467 return sprintf(buf, "%i\n", card->options.add_hhlen);
468}
469
470static ssize_t
471qeth_dev_add_hhlen_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
472{
473 struct qeth_card *card = dev->driver_data;
474 char *tmp;
475 int i;
476
477 if (!card)
478 return -EINVAL;
479
480 if ((card->state != CARD_STATE_DOWN) &&
481 (card->state != CARD_STATE_RECOVER))
482 return -EPERM;
483
484 i = simple_strtoul(buf, &tmp, 10);
485 if ((i < 0) || (i > MAX_ADD_HHLEN)) {
486 PRINT_WARN("add_hhlen out of range\n");
487 return -EINVAL;
488 }
489 card->options.add_hhlen = i;
490
491 return count;
492}
493
494static DEVICE_ATTR(add_hhlen, 0644, qeth_dev_add_hhlen_show,
495 qeth_dev_add_hhlen_store);
496
497static ssize_t
498qeth_dev_fake_ll_show(struct device *dev, struct device_attribute *attr, char *buf)
499{
500 struct qeth_card *card = dev->driver_data;
501
502 if (!card)
503 return -EINVAL;
504
505 return sprintf(buf, "%i\n", card->options.fake_ll? 1:0);
506}
507
508static ssize_t
509qeth_dev_fake_ll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
510{
511 struct qeth_card *card = dev->driver_data;
512 char *tmp;
513 int i;
514
515 if (!card)
516 return -EINVAL;
517
518 if ((card->state != CARD_STATE_DOWN) &&
519 (card->state != CARD_STATE_RECOVER))
520 return -EPERM;
521
522 i = simple_strtoul(buf, &tmp, 16);
523 if ((i != 0) && (i != 1)) {
524 PRINT_WARN("fake_ll: write 0 or 1 to this file!\n");
525 return -EINVAL;
526 }
527 card->options.fake_ll = i;
528 return count;
529}
530
531static DEVICE_ATTR(fake_ll, 0644, qeth_dev_fake_ll_show,
532 qeth_dev_fake_ll_store);
533
534static ssize_t
535qeth_dev_fake_broadcast_show(struct device *dev, struct device_attribute *attr, char *buf)
536{
537 struct qeth_card *card = dev->driver_data;
538
539 if (!card)
540 return -EINVAL;
541
542 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
543}
544
545static ssize_t
546qeth_dev_fake_broadcast_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
547{
548 struct qeth_card *card = dev->driver_data;
549 char *tmp;
550 int i;
551
552 if (!card)
553 return -EINVAL;
554
555 if ((card->state != CARD_STATE_DOWN) &&
556 (card->state != CARD_STATE_RECOVER))
557 return -EPERM;
558
559 i = simple_strtoul(buf, &tmp, 16);
560 if ((i == 0) || (i == 1))
561 card->options.fake_broadcast = i;
562 else {
563 PRINT_WARN("fake_broadcast: write 0 or 1 to this file!\n");
564 return -EINVAL;
565 }
566 return count;
567}
568
569static DEVICE_ATTR(fake_broadcast, 0644, qeth_dev_fake_broadcast_show,
570 qeth_dev_fake_broadcast_store);
571
572static ssize_t
573qeth_dev_recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
574{
575 struct qeth_card *card = dev->driver_data;
576 char *tmp;
577 int i;
578
579 if (!card)
580 return -EINVAL;
581
582 if (card->state != CARD_STATE_UP)
583 return -EPERM;
584
585 i = simple_strtoul(buf, &tmp, 16);
586 if (i == 1)
587 qeth_schedule_recovery(card);
588
589 return count;
590}
591
592static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
593
594static ssize_t
595qeth_dev_broadcast_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
596{
597 struct qeth_card *card = dev->driver_data;
598
599 if (!card)
600 return -EINVAL;
601
602 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
603 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
604 return sprintf(buf, "n/a\n");
605
606 return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
607 QETH_TR_BROADCAST_ALLRINGS)?
608 "all rings":"local");
609}
610
611static ssize_t
612qeth_dev_broadcast_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
613{
614 struct qeth_card *card = dev->driver_data;
615 char *tmp;
616
617 if (!card)
618 return -EINVAL;
619
620 if ((card->state != CARD_STATE_DOWN) &&
621 (card->state != CARD_STATE_RECOVER))
622 return -EPERM;
623
624 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
625 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))){
626 PRINT_WARN("Device is not a tokenring device!\n");
627 return -EINVAL;
628 }
629
630 tmp = strsep((char **) &buf, "\n");
631
632 if (!strcmp(tmp, "local")){
633 card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
634 return count;
635 } else if (!strcmp(tmp, "all_rings")) {
636 card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
637 return count;
638 } else {
639 PRINT_WARN("broadcast_mode: invalid mode %s!\n",
640 tmp);
641 return -EINVAL;
642 }
643 return count;
644}
645
646static DEVICE_ATTR(broadcast_mode, 0644, qeth_dev_broadcast_mode_show,
647 qeth_dev_broadcast_mode_store);
648
649static ssize_t
650qeth_dev_canonical_macaddr_show(struct device *dev, struct device_attribute *attr, char *buf)
651{
652 struct qeth_card *card = dev->driver_data;
653
654 if (!card)
655 return -EINVAL;
656
657 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
658 (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
659 return sprintf(buf, "n/a\n");
660
661 return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
662 QETH_TR_MACADDR_CANONICAL)? 1:0);
663}
664
665static ssize_t
666qeth_dev_canonical_macaddr_store(struct device *dev, struct device_attribute *attr, const char *buf,
667 size_t count)
668{
669 struct qeth_card *card = dev->driver_data;
670 char *tmp;
671 int i;
672
673 if (!card)
674 return -EINVAL;
675
676 if ((card->state != CARD_STATE_DOWN) &&
677 (card->state != CARD_STATE_RECOVER))
678 return -EPERM;
679
680 if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
681 (card->info.link_type == QETH_LINK_TYPE_LANE_TR))){
682 PRINT_WARN("Device is not a tokenring device!\n");
683 return -EINVAL;
684 }
685
686 i = simple_strtoul(buf, &tmp, 16);
687 if ((i == 0) || (i == 1))
688 card->options.macaddr_mode = i?
689 QETH_TR_MACADDR_CANONICAL :
690 QETH_TR_MACADDR_NONCANONICAL;
691 else {
692 PRINT_WARN("canonical_macaddr: write 0 or 1 to this file!\n");
693 return -EINVAL;
694 }
695 return count;
696}
697
698static DEVICE_ATTR(canonical_macaddr, 0644, qeth_dev_canonical_macaddr_show,
699 qeth_dev_canonical_macaddr_store);
700
701static ssize_t
702qeth_dev_layer2_show(struct device *dev, struct device_attribute *attr, char *buf)
703{
704 struct qeth_card *card = dev->driver_data;
705
706 if (!card)
707 return -EINVAL;
708
709 return sprintf(buf, "%i\n", card->options.layer2 ? 1:0);
710}
711
712static ssize_t
713qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
714{
715 struct qeth_card *card = dev->driver_data;
716 char *tmp;
717 int i;
718
719 if (!card)
720 return -EINVAL;
721 if (card->info.type == QETH_CARD_TYPE_IQD) {
722 PRINT_WARN("Layer2 on Hipersockets is not supported! \n");
723 return -EPERM;
724 }
725
726 if (((card->state != CARD_STATE_DOWN) &&
727 (card->state != CARD_STATE_RECOVER)))
728 return -EPERM;
729
730 i = simple_strtoul(buf, &tmp, 16);
731 if ((i == 0) || (i == 1))
732 card->options.layer2 = i;
733 else {
734 PRINT_WARN("layer2: write 0 or 1 to this file!\n");
735 return -EINVAL;
736 }
737 return count;
738}
739
740static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
741 qeth_dev_layer2_store);
742
743static ssize_t
744qeth_dev_performance_stats_show(struct device *dev, struct device_attribute *attr, char *buf)
745{
746 struct qeth_card *card = dev->driver_data;
747
748 if (!card)
749 return -EINVAL;
750
751 return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
752}
753
754static ssize_t
755qeth_dev_performance_stats_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
756{
757 struct qeth_card *card = dev->driver_data;
758 char *tmp;
759 int i;
760
761 if (!card)
762 return -EINVAL;
763
764 i = simple_strtoul(buf, &tmp, 16);
765 if ((i == 0) || (i == 1)) {
766 if (i == card->options.performance_stats)
767 return count;
768 card->options.performance_stats = i;
769 if (i == 0)
770 memset(&card->perf_stats, 0,
771 sizeof(struct qeth_perf_stats));
772 card->perf_stats.initial_rx_packets = card->stats.rx_packets;
773 card->perf_stats.initial_tx_packets = card->stats.tx_packets;
774 } else {
775 PRINT_WARN("performance_stats: write 0 or 1 to this file!\n");
776 return -EINVAL;
777 }
778 return count;
779}
780
781static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
782 qeth_dev_performance_stats_store);
783
784static ssize_t
785qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf)
786{
787 struct qeth_card *card = dev->driver_data;
788
789 if (!card)
790 return -EINVAL;
791
792 switch (card->options.large_send) {
793 case QETH_LARGE_SEND_NO:
794 return sprintf(buf, "%s\n", "no");
795 case QETH_LARGE_SEND_EDDP:
796 return sprintf(buf, "%s\n", "EDDP");
797 case QETH_LARGE_SEND_TSO:
798 return sprintf(buf, "%s\n", "TSO");
799 default:
800 return sprintf(buf, "%s\n", "N/A");
801 }
802}
803
804static ssize_t
805qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
806{
807 struct qeth_card *card = dev->driver_data;
808 enum qeth_large_send_types type;
809 int rc = 0;
810 char *tmp;
811
812 if (!card)
813 return -EINVAL;
814 tmp = strsep((char **) &buf, "\n");
815 if (!strcmp(tmp, "no")){
816 type = QETH_LARGE_SEND_NO;
817 } else if (!strcmp(tmp, "EDDP")) {
818 type = QETH_LARGE_SEND_EDDP;
819 } else if (!strcmp(tmp, "TSO")) {
820 type = QETH_LARGE_SEND_TSO;
821 } else {
822 PRINT_WARN("large_send: invalid mode %s!\n", tmp);
823 return -EINVAL;
824 }
825 if (card->options.large_send == type)
826 return count;
827 if ((rc = qeth_set_large_send(card, type)))
828 return rc;
829 return count;
830}
831
832static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
833 qeth_dev_large_send_store);
834
835static ssize_t
836qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value )
837{
838
839 if (!card)
840 return -EINVAL;
841
842 return sprintf(buf, "%i\n", value);
843}
844
845static ssize_t
846qeth_dev_blkt_store(struct qeth_card *card, const char *buf, size_t count,
847 int *value, int max_value)
848{
849 char *tmp;
850 int i;
851
852 if (!card)
853 return -EINVAL;
854
855 if ((card->state != CARD_STATE_DOWN) &&
856 (card->state != CARD_STATE_RECOVER))
857 return -EPERM;
858
859 i = simple_strtoul(buf, &tmp, 10);
860 if (i <= max_value) {
861 *value = i;
862 } else {
863 PRINT_WARN("blkt total time: write values between"
864 " 0 and %d to this file!\n", max_value);
865 return -EINVAL;
866 }
867 return count;
868}
869
870static ssize_t
871qeth_dev_blkt_total_show(struct device *dev, struct device_attribute *attr, char *buf)
872{
873 struct qeth_card *card = dev->driver_data;
874
875 return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);
876}
877
878
879static ssize_t
880qeth_dev_blkt_total_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
881{
882 struct qeth_card *card = dev->driver_data;
883
884 return qeth_dev_blkt_store(card, buf, count,
885 &card->info.blkt.time_total,1000);
886}
887
888
889
890static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
891 qeth_dev_blkt_total_store);
892
893static ssize_t
894qeth_dev_blkt_inter_show(struct device *dev, struct device_attribute *attr, char *buf)
895{
896 struct qeth_card *card = dev->driver_data;
897
898 return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);
899}
900
901
902static ssize_t
903qeth_dev_blkt_inter_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
904{
905 struct qeth_card *card = dev->driver_data;
906
907 return qeth_dev_blkt_store(card, buf, count,
908 &card->info.blkt.inter_packet,100);
909}
910
911static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
912 qeth_dev_blkt_inter_store);
913
914static ssize_t
915qeth_dev_blkt_inter_jumbo_show(struct device *dev, struct device_attribute *attr, char *buf)
916{
917 struct qeth_card *card = dev->driver_data;
918
919 return qeth_dev_blkt_show(buf, card,
920 card->info.blkt.inter_packet_jumbo);
921}
922
923
924static ssize_t
925qeth_dev_blkt_inter_jumbo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
926{
927 struct qeth_card *card = dev->driver_data;
928
929 return qeth_dev_blkt_store(card, buf, count,
930 &card->info.blkt.inter_packet_jumbo,100);
931}
932
933static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
934 qeth_dev_blkt_inter_jumbo_store);
935
936static struct device_attribute * qeth_blkt_device_attrs[] = {
937 &dev_attr_total,
938 &dev_attr_inter,
939 &dev_attr_inter_jumbo,
940 NULL,
941};
942
943static struct attribute_group qeth_device_blkt_group = {
944 .name = "blkt",
945 .attrs = (struct attribute **)qeth_blkt_device_attrs,
946};
947
948static struct device_attribute * qeth_device_attrs[] = {
949 &dev_attr_state,
950 &dev_attr_chpid,
951 &dev_attr_if_name,
952 &dev_attr_card_type,
953 &dev_attr_portno,
954 &dev_attr_portname,
955 &dev_attr_checksumming,
956 &dev_attr_priority_queueing,
957 &dev_attr_buffer_count,
958 &dev_attr_route4,
959#ifdef CONFIG_QETH_IPV6
960 &dev_attr_route6,
961#endif
962 &dev_attr_add_hhlen,
963 &dev_attr_fake_ll,
964 &dev_attr_fake_broadcast,
965 &dev_attr_recover,
966 &dev_attr_broadcast_mode,
967 &dev_attr_canonical_macaddr,
968 &dev_attr_layer2,
969 &dev_attr_large_send,
970 &dev_attr_performance_stats,
971 NULL,
972};
973
974static struct attribute_group qeth_device_attr_group = {
975 .attrs = (struct attribute **)qeth_device_attrs,
976};
977
978static struct device_attribute * qeth_osn_device_attrs[] = {
979 &dev_attr_state,
980 &dev_attr_chpid,
981 &dev_attr_if_name,
982 &dev_attr_card_type,
983 &dev_attr_buffer_count,
984 &dev_attr_recover,
985 NULL,
986};
987
988static struct attribute_group qeth_osn_device_attr_group = {
989 .attrs = (struct attribute **)qeth_osn_device_attrs,
990};
991
992#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \
993struct device_attribute dev_attr_##_id = { \
994 .attr = {.name=__stringify(_name), .mode=_mode, },\
995 .show = _show, \
996 .store = _store, \
997};
998
999static int
1000qeth_check_layer2(struct qeth_card *card)
1001{
1002 if (card->options.layer2)
1003 return -EPERM;
1004 return 0;
1005}
1006
1007
1008static ssize_t
1009qeth_dev_ipato_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
1010{
1011 struct qeth_card *card = dev->driver_data;
1012
1013 if (!card)
1014 return -EINVAL;
1015
1016 if (qeth_check_layer2(card))
1017 return -EPERM;
1018 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
1019}
1020
1021static ssize_t
1022qeth_dev_ipato_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1023{
1024 struct qeth_card *card = dev->driver_data;
1025 char *tmp;
1026
1027 if (!card)
1028 return -EINVAL;
1029
1030 if ((card->state != CARD_STATE_DOWN) &&
1031 (card->state != CARD_STATE_RECOVER))
1032 return -EPERM;
1033
1034 if (qeth_check_layer2(card))
1035 return -EPERM;
1036
1037 tmp = strsep((char **) &buf, "\n");
1038 if (!strcmp(tmp, "toggle")){
1039 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
1040 } else if (!strcmp(tmp, "1")){
1041 card->ipato.enabled = 1;
1042 } else if (!strcmp(tmp, "0")){
1043 card->ipato.enabled = 0;
1044 } else {
1045 PRINT_WARN("ipato_enable: write 0, 1 or 'toggle' to "
1046 "this file\n");
1047 return -EINVAL;
1048 }
1049 return count;
1050}
1051
1052static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
1053 qeth_dev_ipato_enable_show,
1054 qeth_dev_ipato_enable_store);
1055
1056static ssize_t
1057qeth_dev_ipato_invert4_show(struct device *dev, struct device_attribute *attr, char *buf)
1058{
1059 struct qeth_card *card = dev->driver_data;
1060
1061 if (!card)
1062 return -EINVAL;
1063
1064 if (qeth_check_layer2(card))
1065 return -EPERM;
1066
1067 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
1068}
1069
1070static ssize_t
1071qeth_dev_ipato_invert4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1072{
1073 struct qeth_card *card = dev->driver_data;
1074 char *tmp;
1075
1076 if (!card)
1077 return -EINVAL;
1078
1079 if (qeth_check_layer2(card))
1080 return -EPERM;
1081
1082 tmp = strsep((char **) &buf, "\n");
1083 if (!strcmp(tmp, "toggle")){
1084 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
1085 } else if (!strcmp(tmp, "1")){
1086 card->ipato.invert4 = 1;
1087 } else if (!strcmp(tmp, "0")){
1088 card->ipato.invert4 = 0;
1089 } else {
1090 PRINT_WARN("ipato_invert4: write 0, 1 or 'toggle' to "
1091 "this file\n");
1092 return -EINVAL;
1093 }
1094 return count;
1095}
1096
1097static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
1098 qeth_dev_ipato_invert4_show,
1099 qeth_dev_ipato_invert4_store);
1100
1101static ssize_t
1102qeth_dev_ipato_add_show(char *buf, struct qeth_card *card,
1103 enum qeth_prot_versions proto)
1104{
1105 struct qeth_ipato_entry *ipatoe;
1106 unsigned long flags;
1107 char addr_str[40];
1108 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
1109 int i = 0;
1110
1111 if (qeth_check_layer2(card))
1112 return -EPERM;
1113
1114 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
1115 /* add strlen for "/<mask>\n" */
1116 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
1117 spin_lock_irqsave(&card->ip_lock, flags);
1118 list_for_each_entry(ipatoe, &card->ipato.entries, entry){
1119 if (ipatoe->proto != proto)
1120 continue;
1121 /* String must not be longer than PAGE_SIZE. So we check if
1122 * string length gets near PAGE_SIZE. Then we can savely display
1123 * the next IPv6 address (worst case, compared to IPv4) */
1124 if ((PAGE_SIZE - i) <= entry_len)
1125 break;
1126 qeth_ipaddr_to_string(proto, ipatoe->addr, addr_str);
1127 i += snprintf(buf + i, PAGE_SIZE - i,
1128 "%s/%i\n", addr_str, ipatoe->mask_bits);
1129 }
1130 spin_unlock_irqrestore(&card->ip_lock, flags);
1131 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
1132
1133 return i;
1134}
1135
1136static ssize_t
1137qeth_dev_ipato_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
1138{
1139 struct qeth_card *card = dev->driver_data;
1140
1141 if (!card)
1142 return -EINVAL;
1143
1144 return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
1145}
1146
1147static int
1148qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
1149 u8 *addr, int *mask_bits)
1150{
1151 const char *start, *end;
1152 char *tmp;
1153 char buffer[40] = {0, };
1154
1155 start = buf;
1156 /* get address string */
1157 end = strchr(start, '/');
1158 if (!end || (end - start >= 40)){
1159 PRINT_WARN("Invalid format for ipato_addx/delx. "
1160 "Use <ip addr>/<mask bits>\n");
1161 return -EINVAL;
1162 }
1163 strncpy(buffer, start, end - start);
1164 if (qeth_string_to_ipaddr(buffer, proto, addr)){
1165 PRINT_WARN("Invalid IP address format!\n");
1166 return -EINVAL;
1167 }
1168 start = end + 1;
1169 *mask_bits = simple_strtoul(start, &tmp, 10);
1170 if (!strlen(start) ||
1171 (tmp == start) ||
1172 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
1173 PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n");
1174 return -EINVAL;
1175 }
1176 return 0;
1177}
1178
1179static ssize_t
1180qeth_dev_ipato_add_store(const char *buf, size_t count,
1181 struct qeth_card *card, enum qeth_prot_versions proto)
1182{
1183 struct qeth_ipato_entry *ipatoe;
1184 u8 addr[16];
1185 int mask_bits;
1186 int rc;
1187
1188 if (qeth_check_layer2(card))
1189 return -EPERM;
1190 if ((rc = qeth_parse_ipatoe(buf, proto, addr, &mask_bits)))
1191 return rc;
1192
1193 if (!(ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL))){
1194 PRINT_WARN("No memory to allocate ipato entry\n");
1195 return -ENOMEM;
1196 }
1197 ipatoe->proto = proto;
1198 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
1199 ipatoe->mask_bits = mask_bits;
1200
1201 if ((rc = qeth_add_ipato_entry(card, ipatoe))){
1202 kfree(ipatoe);
1203 return rc;
1204 }
1205
1206 return count;
1207}
1208
1209static ssize_t
1210qeth_dev_ipato_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1211{
1212 struct qeth_card *card = dev->driver_data;
1213
1214 if (!card)
1215 return -EINVAL;
1216
1217 return qeth_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
1218}
1219
1220static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
1221 qeth_dev_ipato_add4_show,
1222 qeth_dev_ipato_add4_store);
1223
1224static ssize_t
1225qeth_dev_ipato_del_store(const char *buf, size_t count,
1226 struct qeth_card *card, enum qeth_prot_versions proto)
1227{
1228 u8 addr[16];
1229 int mask_bits;
1230 int rc;
1231
1232 if (qeth_check_layer2(card))
1233 return -EPERM;
1234 if ((rc = qeth_parse_ipatoe(buf, proto, addr, &mask_bits)))
1235 return rc;
1236
1237 qeth_del_ipato_entry(card, proto, addr, mask_bits);
1238
1239 return count;
1240}
1241
1242static ssize_t
1243qeth_dev_ipato_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1244{
1245 struct qeth_card *card = dev->driver_data;
1246
1247 if (!card)
1248 return -EINVAL;
1249
1250 return qeth_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
1251}
1252
1253static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
1254 qeth_dev_ipato_del4_store);
1255
1256#ifdef CONFIG_QETH_IPV6
1257static ssize_t
1258qeth_dev_ipato_invert6_show(struct device *dev, struct device_attribute *attr, char *buf)
1259{
1260 struct qeth_card *card = dev->driver_data;
1261
1262 if (!card)
1263 return -EINVAL;
1264
1265 if (qeth_check_layer2(card))
1266 return -EPERM;
1267
1268 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
1269}
1270
1271static ssize_t
1272qeth_dev_ipato_invert6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1273{
1274 struct qeth_card *card = dev->driver_data;
1275 char *tmp;
1276
1277 if (!card)
1278 return -EINVAL;
1279
1280 if (qeth_check_layer2(card))
1281 return -EPERM;
1282
1283 tmp = strsep((char **) &buf, "\n");
1284 if (!strcmp(tmp, "toggle")){
1285 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
1286 } else if (!strcmp(tmp, "1")){
1287 card->ipato.invert6 = 1;
1288 } else if (!strcmp(tmp, "0")){
1289 card->ipato.invert6 = 0;
1290 } else {
1291 PRINT_WARN("ipato_invert6: write 0, 1 or 'toggle' to "
1292 "this file\n");
1293 return -EINVAL;
1294 }
1295 return count;
1296}
1297
1298static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
1299 qeth_dev_ipato_invert6_show,
1300 qeth_dev_ipato_invert6_store);
1301
1302
1303static ssize_t
1304qeth_dev_ipato_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
1305{
1306 struct qeth_card *card = dev->driver_data;
1307
1308 if (!card)
1309 return -EINVAL;
1310
1311 return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
1312}
1313
1314static ssize_t
1315qeth_dev_ipato_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1316{
1317 struct qeth_card *card = dev->driver_data;
1318
1319 if (!card)
1320 return -EINVAL;
1321
1322 return qeth_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
1323}
1324
1325static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
1326 qeth_dev_ipato_add6_show,
1327 qeth_dev_ipato_add6_store);
1328
1329static ssize_t
1330qeth_dev_ipato_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1331{
1332 struct qeth_card *card = dev->driver_data;
1333
1334 if (!card)
1335 return -EINVAL;
1336
1337 return qeth_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
1338}
1339
1340static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
1341 qeth_dev_ipato_del6_store);
1342#endif /* CONFIG_QETH_IPV6 */
1343
1344static struct device_attribute * qeth_ipato_device_attrs[] = {
1345 &dev_attr_ipato_enable,
1346 &dev_attr_ipato_invert4,
1347 &dev_attr_ipato_add4,
1348 &dev_attr_ipato_del4,
1349#ifdef CONFIG_QETH_IPV6
1350 &dev_attr_ipato_invert6,
1351 &dev_attr_ipato_add6,
1352 &dev_attr_ipato_del6,
1353#endif
1354 NULL,
1355};
1356
1357static struct attribute_group qeth_device_ipato_group = {
1358 .name = "ipa_takeover",
1359 .attrs = (struct attribute **)qeth_ipato_device_attrs,
1360};
1361
1362static ssize_t
1363qeth_dev_vipa_add_show(char *buf, struct qeth_card *card,
1364 enum qeth_prot_versions proto)
1365{
1366 struct qeth_ipaddr *ipaddr;
1367 char addr_str[40];
1368 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
1369 unsigned long flags;
1370 int i = 0;
1371
1372 if (qeth_check_layer2(card))
1373 return -EPERM;
1374
1375 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
1376 entry_len += 2; /* \n + terminator */
1377 spin_lock_irqsave(&card->ip_lock, flags);
1378 list_for_each_entry(ipaddr, &card->ip_list, entry){
1379 if (ipaddr->proto != proto)
1380 continue;
1381 if (ipaddr->type != QETH_IP_TYPE_VIPA)
1382 continue;
1383 /* String must not be longer than PAGE_SIZE. So we check if
1384 * string length gets near PAGE_SIZE. Then we can savely display
1385 * the next IPv6 address (worst case, compared to IPv4) */
1386 if ((PAGE_SIZE - i) <= entry_len)
1387 break;
1388 qeth_ipaddr_to_string(proto, (const u8 *)&ipaddr->u, addr_str);
1389 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
1390 }
1391 spin_unlock_irqrestore(&card->ip_lock, flags);
1392 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
1393
1394 return i;
1395}
1396
1397static ssize_t
1398qeth_dev_vipa_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
1399{
1400 struct qeth_card *card = dev->driver_data;
1401
1402 if (!card)
1403 return -EINVAL;
1404
1405 return qeth_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
1406}
1407
1408static int
1409qeth_parse_vipae(const char* buf, enum qeth_prot_versions proto,
1410 u8 *addr)
1411{
1412 if (qeth_string_to_ipaddr(buf, proto, addr)){
1413 PRINT_WARN("Invalid IP address format!\n");
1414 return -EINVAL;
1415 }
1416 return 0;
1417}
1418
1419static ssize_t
1420qeth_dev_vipa_add_store(const char *buf, size_t count,
1421 struct qeth_card *card, enum qeth_prot_versions proto)
1422{
1423 u8 addr[16] = {0, };
1424 int rc;
1425
1426 if (qeth_check_layer2(card))
1427 return -EPERM;
1428 if ((rc = qeth_parse_vipae(buf, proto, addr)))
1429 return rc;
1430
1431 if ((rc = qeth_add_vipa(card, proto, addr)))
1432 return rc;
1433
1434 return count;
1435}
1436
1437static ssize_t
1438qeth_dev_vipa_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1439{
1440 struct qeth_card *card = dev->driver_data;
1441
1442 if (!card)
1443 return -EINVAL;
1444
1445 return qeth_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
1446}
1447
1448static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
1449 qeth_dev_vipa_add4_show,
1450 qeth_dev_vipa_add4_store);
1451
1452static ssize_t
1453qeth_dev_vipa_del_store(const char *buf, size_t count,
1454 struct qeth_card *card, enum qeth_prot_versions proto)
1455{
1456 u8 addr[16];
1457 int rc;
1458
1459 if (qeth_check_layer2(card))
1460 return -EPERM;
1461 if ((rc = qeth_parse_vipae(buf, proto, addr)))
1462 return rc;
1463
1464 qeth_del_vipa(card, proto, addr);
1465
1466 return count;
1467}
1468
1469static ssize_t
1470qeth_dev_vipa_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1471{
1472 struct qeth_card *card = dev->driver_data;
1473
1474 if (!card)
1475 return -EINVAL;
1476
1477 return qeth_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
1478}
1479
1480static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
1481 qeth_dev_vipa_del4_store);
1482
1483#ifdef CONFIG_QETH_IPV6
1484static ssize_t
1485qeth_dev_vipa_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
1486{
1487 struct qeth_card *card = dev->driver_data;
1488
1489 if (!card)
1490 return -EINVAL;
1491
1492 return qeth_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
1493}
1494
1495static ssize_t
1496qeth_dev_vipa_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1497{
1498 struct qeth_card *card = dev->driver_data;
1499
1500 if (!card)
1501 return -EINVAL;
1502
1503 return qeth_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
1504}
1505
1506static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
1507 qeth_dev_vipa_add6_show,
1508 qeth_dev_vipa_add6_store);
1509
1510static ssize_t
1511qeth_dev_vipa_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1512{
1513 struct qeth_card *card = dev->driver_data;
1514
1515 if (!card)
1516 return -EINVAL;
1517
1518 if (qeth_check_layer2(card))
1519 return -EPERM;
1520
1521 return qeth_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
1522}
1523
1524static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
1525 qeth_dev_vipa_del6_store);
1526#endif /* CONFIG_QETH_IPV6 */
1527
1528static struct device_attribute * qeth_vipa_device_attrs[] = {
1529 &dev_attr_vipa_add4,
1530 &dev_attr_vipa_del4,
1531#ifdef CONFIG_QETH_IPV6
1532 &dev_attr_vipa_add6,
1533 &dev_attr_vipa_del6,
1534#endif
1535 NULL,
1536};
1537
1538static struct attribute_group qeth_device_vipa_group = {
1539 .name = "vipa",
1540 .attrs = (struct attribute **)qeth_vipa_device_attrs,
1541};
1542
1543static ssize_t
1544qeth_dev_rxip_add_show(char *buf, struct qeth_card *card,
1545 enum qeth_prot_versions proto)
1546{
1547 struct qeth_ipaddr *ipaddr;
1548 char addr_str[40];
1549 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
1550 unsigned long flags;
1551 int i = 0;
1552
1553 if (qeth_check_layer2(card))
1554 return -EPERM;
1555
1556 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
1557 entry_len += 2; /* \n + terminator */
1558 spin_lock_irqsave(&card->ip_lock, flags);
1559 list_for_each_entry(ipaddr, &card->ip_list, entry){
1560 if (ipaddr->proto != proto)
1561 continue;
1562 if (ipaddr->type != QETH_IP_TYPE_RXIP)
1563 continue;
1564 /* String must not be longer than PAGE_SIZE. So we check if
1565 * string length gets near PAGE_SIZE. Then we can savely display
1566 * the next IPv6 address (worst case, compared to IPv4) */
1567 if ((PAGE_SIZE - i) <= entry_len)
1568 break;
1569 qeth_ipaddr_to_string(proto, (const u8 *)&ipaddr->u, addr_str);
1570 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
1571 }
1572 spin_unlock_irqrestore(&card->ip_lock, flags);
1573 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
1574
1575 return i;
1576}
1577
1578static ssize_t
1579qeth_dev_rxip_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
1580{
1581 struct qeth_card *card = dev->driver_data;
1582
1583 if (!card)
1584 return -EINVAL;
1585
1586 return qeth_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
1587}
1588
1589static int
1590qeth_parse_rxipe(const char* buf, enum qeth_prot_versions proto,
1591 u8 *addr)
1592{
1593 if (qeth_string_to_ipaddr(buf, proto, addr)){
1594 PRINT_WARN("Invalid IP address format!\n");
1595 return -EINVAL;
1596 }
1597 return 0;
1598}
1599
1600static ssize_t
1601qeth_dev_rxip_add_store(const char *buf, size_t count,
1602 struct qeth_card *card, enum qeth_prot_versions proto)
1603{
1604 u8 addr[16] = {0, };
1605 int rc;
1606
1607 if (qeth_check_layer2(card))
1608 return -EPERM;
1609 if ((rc = qeth_parse_rxipe(buf, proto, addr)))
1610 return rc;
1611
1612 if ((rc = qeth_add_rxip(card, proto, addr)))
1613 return rc;
1614
1615 return count;
1616}
1617
1618static ssize_t
1619qeth_dev_rxip_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1620{
1621 struct qeth_card *card = dev->driver_data;
1622
1623 if (!card)
1624 return -EINVAL;
1625
1626 return qeth_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
1627}
1628
1629static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
1630 qeth_dev_rxip_add4_show,
1631 qeth_dev_rxip_add4_store);
1632
1633static ssize_t
1634qeth_dev_rxip_del_store(const char *buf, size_t count,
1635 struct qeth_card *card, enum qeth_prot_versions proto)
1636{
1637 u8 addr[16];
1638 int rc;
1639
1640 if (qeth_check_layer2(card))
1641 return -EPERM;
1642 if ((rc = qeth_parse_rxipe(buf, proto, addr)))
1643 return rc;
1644
1645 qeth_del_rxip(card, proto, addr);
1646
1647 return count;
1648}
1649
1650static ssize_t
1651qeth_dev_rxip_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1652{
1653 struct qeth_card *card = dev->driver_data;
1654
1655 if (!card)
1656 return -EINVAL;
1657
1658 return qeth_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
1659}
1660
1661static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
1662 qeth_dev_rxip_del4_store);
1663
1664#ifdef CONFIG_QETH_IPV6
1665static ssize_t
1666qeth_dev_rxip_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
1667{
1668 struct qeth_card *card = dev->driver_data;
1669
1670 if (!card)
1671 return -EINVAL;
1672
1673 return qeth_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
1674}
1675
1676static ssize_t
1677qeth_dev_rxip_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1678{
1679 struct qeth_card *card = dev->driver_data;
1680
1681 if (!card)
1682 return -EINVAL;
1683
1684 return qeth_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
1685}
1686
1687static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
1688 qeth_dev_rxip_add6_show,
1689 qeth_dev_rxip_add6_store);
1690
1691static ssize_t
1692qeth_dev_rxip_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1693{
1694 struct qeth_card *card = dev->driver_data;
1695
1696 if (!card)
1697 return -EINVAL;
1698
1699 return qeth_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1700}
1701
1702static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1703 qeth_dev_rxip_del6_store);
1704#endif /* CONFIG_QETH_IPV6 */
1705
1706static struct device_attribute * qeth_rxip_device_attrs[] = {
1707 &dev_attr_rxip_add4,
1708 &dev_attr_rxip_del4,
1709#ifdef CONFIG_QETH_IPV6
1710 &dev_attr_rxip_add6,
1711 &dev_attr_rxip_del6,
1712#endif
1713 NULL,
1714};
1715
1716static struct attribute_group qeth_device_rxip_group = {
1717 .name = "rxip",
1718 .attrs = (struct attribute **)qeth_rxip_device_attrs,
1719};
1720
1721int
1722qeth_create_device_attributes(struct device *dev)
1723{
1724 int ret;
1725 struct qeth_card *card = dev->driver_data;
1726
1727 if (card->info.type == QETH_CARD_TYPE_OSN)
1728 return sysfs_create_group(&dev->kobj,
1729 &qeth_osn_device_attr_group);
1730
1731 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group)))
1732 return ret;
1733 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){
1734 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
1735 return ret;
1736 }
1737 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group))){
1738 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
1739 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1740 return ret;
1741 }
1742 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group))){
1743 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
1744 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1745 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1746 return ret;
1747 }
1748 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group))){
1749 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
1750 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1751 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1752 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1753 return ret;
1754 }
1755 return 0;
1756}
1757
1758void
1759qeth_remove_device_attributes(struct device *dev)
1760{
1761 struct qeth_card *card = dev->driver_data;
1762
1763 if (card->info.type == QETH_CARD_TYPE_OSN) {
1764 sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
1765 return;
1766 }
1767 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
1768 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1769 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1770 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1771 sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group);
1772}
1773
1774/**********************/
1775/* DRIVER ATTRIBUTES */
1776/**********************/
1777static ssize_t
1778qeth_driver_group_store(struct device_driver *ddrv, const char *buf,
1779 size_t count)
1780{
1781 const char *start, *end;
1782 char bus_ids[3][BUS_ID_SIZE], *argv[3];
1783 int i;
1784 int err;
1785
1786 start = buf;
1787 for (i = 0; i < 3; i++) {
1788 static const char delim[] = { ',', ',', '\n' };
1789 int len;
1790
1791 if (!(end = strchr(start, delim[i])))
1792 return -EINVAL;
1793 len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start);
1794 strncpy(bus_ids[i], start, len);
1795 bus_ids[i][len] = '\0';
1796 start = end + 1;
1797 argv[i] = bus_ids[i];
1798 }
1799 err = ccwgroup_create(qeth_root_dev, qeth_ccwgroup_driver.driver_id,
1800 &qeth_ccw_driver, 3, argv);
1801 if (err)
1802 return err;
1803 else
1804 return count;
1805}
1806
1807
1808static DRIVER_ATTR(group, 0200, NULL, qeth_driver_group_store);
1809
1810static ssize_t
1811qeth_driver_notifier_register_store(struct device_driver *ddrv, const char *buf,
1812 size_t count)
1813{
1814 int rc;
1815 int signum;
1816 char *tmp, *tmp2;
1817
1818 tmp = strsep((char **) &buf, "\n");
1819 if (!strncmp(tmp, "unregister", 10)){
1820 if ((rc = qeth_notifier_unregister(current)))
1821 return rc;
1822 return count;
1823 }
1824
1825 signum = simple_strtoul(tmp, &tmp2, 10);
1826 if ((signum < 0) || (signum > 32)){
1827 PRINT_WARN("Signal number %d is out of range\n", signum);
1828 return -EINVAL;
1829 }
1830 if ((rc = qeth_notifier_register(current, signum)))
1831 return rc;
1832
1833 return count;
1834}
1835
1836static DRIVER_ATTR(notifier_register, 0200, NULL,
1837 qeth_driver_notifier_register_store);
1838
1839int
1840qeth_create_driver_attributes(void)
1841{
1842 int rc;
1843
1844 if ((rc = driver_create_file(&qeth_ccwgroup_driver.driver,
1845 &driver_attr_group)))
1846 return rc;
1847 return driver_create_file(&qeth_ccwgroup_driver.driver,
1848 &driver_attr_notifier_register);
1849}
1850
1851void
1852qeth_remove_driver_attributes(void)
1853{
1854 driver_remove_file(&qeth_ccwgroup_driver.driver,
1855 &driver_attr_group);
1856 driver_remove_file(&qeth_ccwgroup_driver.driver,
1857 &driver_attr_notifier_register);
1858}
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
deleted file mode 100644
index c20e923cf9ad..000000000000
--- a/drivers/s390/net/qeth_tso.h
+++ /dev/null
@@ -1,148 +0,0 @@
1/*
2 * linux/drivers/s390/net/qeth_tso.h
3 *
4 * Header file for qeth TCP Segmentation Offload support.
5 *
6 * Copyright 2004 IBM Corporation
7 *
8 * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
9 *
10 */
11#ifndef __QETH_TSO_H__
12#define __QETH_TSO_H__
13
14#include <linux/skbuff.h>
15#include <linux/tcp.h>
16#include <linux/ip.h>
17#include <linux/ipv6.h>
18#include <net/ip6_checksum.h>
19#include "qeth.h"
20#include "qeth_mpc.h"
21
22
23static inline struct qeth_hdr_tso *
24qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
25{
26 QETH_DBF_TEXT(trace, 5, "tsoprsk");
27 return qeth_push_skb(card, *skb, sizeof(struct qeth_hdr_tso));
28}
29
30/**
31 * fill header for a TSO packet
32 */
33static inline void
34qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb)
35{
36 struct qeth_hdr_tso *hdr;
37 struct tcphdr *tcph;
38 struct iphdr *iph;
39
40 QETH_DBF_TEXT(trace, 5, "tsofhdr");
41
42 hdr = (struct qeth_hdr_tso *) skb->data;
43 iph = ip_hdr(skb);
44 tcph = tcp_hdr(skb);
45 /*fix header to TSO values ...*/
46 hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
47 /*set values which are fix for the first approach ...*/
48 hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
49 hdr->ext.imb_hdr_no = 1;
50 hdr->ext.hdr_type = 1;
51 hdr->ext.hdr_version = 1;
52 hdr->ext.hdr_len = 28;
53 /*insert non-fix values */
54 hdr->ext.mss = skb_shinfo(skb)->gso_size;
55 hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
56 hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
57 sizeof(struct qeth_hdr_tso));
58}
59
60/**
61 * change some header values as requested by hardware
62 */
63static inline void
64qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
65{
66 struct iphdr *iph = ip_hdr(skb);
67 struct ipv6hdr *ip6h = ipv6_hdr(skb);
68 struct tcphdr *tcph = tcp_hdr(skb);
69
70 tcph->check = 0;
71 if (skb->protocol == ETH_P_IPV6) {
72 ip6h->payload_len = 0;
73 tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
74 0, IPPROTO_TCP, 0);
75 return;
76 }
77 /*OSA want us to set these values ...*/
78 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
79 0, IPPROTO_TCP, 0);
80 iph->tot_len = 0;
81 iph->check = 0;
82}
83
84static inline int
85qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
86 int ipv, int cast_type)
87{
88 struct qeth_hdr_tso *hdr;
89
90 QETH_DBF_TEXT(trace, 5, "tsoprep");
91
92 hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
93 if (hdr == NULL) {
94 QETH_DBF_TEXT(trace, 4, "tsoperr");
95 return -ENOMEM;
96 }
97 memset(hdr, 0, sizeof(struct qeth_hdr_tso));
98 /*fill first 32 bytes of qdio header as used
99 *FIXME: TSO has two struct members
100 * with different names but same size
101 * */
102 qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type);
103 qeth_tso_fill_header(card, skb);
104 qeth_tso_set_tcpip_header(card, skb);
105 return 0;
106}
107
108static inline void
109__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
110 int is_tso, int *next_element_to_fill)
111{
112 struct skb_frag_struct *frag;
113 int fragno;
114 unsigned long addr;
115 int element, cnt, dlen;
116
117 fragno = skb_shinfo(skb)->nr_frags;
118 element = *next_element_to_fill;
119 dlen = 0;
120
121 if (is_tso)
122 buffer->element[element].flags =
123 SBAL_FLAGS_MIDDLE_FRAG;
124 else
125 buffer->element[element].flags =
126 SBAL_FLAGS_FIRST_FRAG;
127 if ( (dlen = (skb->len - skb->data_len)) ) {
128 buffer->element[element].addr = skb->data;
129 buffer->element[element].length = dlen;
130 element++;
131 }
132 for (cnt = 0; cnt < fragno; cnt++) {
133 frag = &skb_shinfo(skb)->frags[cnt];
134 addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
135 frag->page_offset;
136 buffer->element[element].addr = (char *)addr;
137 buffer->element[element].length = frag->size;
138 if (cnt < (fragno - 1))
139 buffer->element[element].flags =
140 SBAL_FLAGS_MIDDLE_FRAG;
141 else
142 buffer->element[element].flags =
143 SBAL_FLAGS_LAST_FRAG;
144 element++;
145 }
146 *next_element_to_fill = element;
147}
148#endif /* __QETH_TSO_H__ */